<!DOCTYPE html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta property="og:type" content="website">
<meta property="og:title" content="kyssion-blog">
<meta property="og:url" content="http://yoursite.com/page/10/index.html">
<meta property="og:site_name" content="kyssion-blog">
<meta property="og:locale" content="zh-Hans">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="kyssion-blog">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/page/10/"/>





  <title>kyssion-blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left 
  page-home">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">kyssion-blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-schedule">
          <a href="/schedule/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-calendar"></i> <br />
            
            日程表
          </a>
        </li>
      
        
        <li class="menu-item menu-item-sitemap">
          <a href="/sitemap.xml" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-sitemap"></i> <br />
            
            站点地图
          </a>
        </li>
      
        
        <li class="menu-item menu-item-commonweal">
          <a href="/404/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br />
            
            公益404
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            
  <section id="posts" class="posts-expand">
    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-System.getProperty(xxxx)方法解惑/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-System.getProperty(xxxx)方法解惑/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <blockquote>
<p>System.getProperty(“java.version”) 方法是输出java的运行环境变量(系统属性)的方法</p>
</blockquote>
<ul>
<li>主要可以输出的数据有:</li>
</ul>
<p>java.version   Java 运行时环境版本<br>java.vendor   Java 运行时环境供应商<br>java.vendor.url   Java 供应商的 URL<br>java.home   Java 安装目录<br>java.vm.specification.version   Java 虚拟机规范版本<br>java.vm.specification.vendor   Java 虚拟机规范供应<br>java.vm.specification.name   Java 虚拟机规范名称<br>java.vm.version   Java 虚拟机实现版本<br>java.vm.vendor   Java 虚拟机实现供应商<br>java.vm.name   Java 虚拟机实现名称<br>java.specification.version   Java 运行时环境规范版本<br>java.specification.vendor   Java 运行时环境规范供应商<br>java.specification.name   Java 运行时环境规范名称<br>java.class.version   Java 类格式版本号<br>java.class.path   Java 类路径<br>java.library.path   加载库时搜索的路径列表<br>java.io.tmpdir   默认的临时文件路径<br>java.compiler   要使用的 JIT 编译器的名称<br>java.ext.dirs   一个或多个扩展目录的路径<br>os.name   操作系统的名称<br>os.arch   操作系统的架构<br>os.version   操作系统的版本<br>file.separator   文件分隔符（在 UNIX 系统中是“/”）<br>path.separator   路径分隔符（在 UNIX 系统中是“:”）<br>line.separator   行分隔符（在 UNIX 系统中是“/n”）<br>user.name   用户的账户名称<br>user.home   用户的主目录<br>user.dir   用户的当前工作目录</p>
<h3 id="java运行环境的设置方法"><a href="#java运行环境的设置方法" class="headerlink" title="java运行环境的设置方法"></a>java运行环境的设置方法</h3><p>其实本质上就是使用jvm虚拟机提供的-D参数</p>
<p>比如设置 <strong>java -Done.xxx.yyy=123</strong></p>
<p>功能解析<br><strong>-D=value</strong><br>官网解释：<br>    Set a system property value. If value is<br>    a string that contains spaces, you must enclose the string in double quotes:<br>在虚拟机的系统属性中设置属性名/值对，运行在此虚拟机上的应用程序可用：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">System.getProperty(<span class="string">"属性名"</span>)</span><br></pre></td></tr></table></figure></p>
<p>得到value的值。<br>如果value中有空格，则需要用双引号将该值括起来，<strong>如：-Dname=”kazaf f”</strong></p>
<p>该参数通常用于设置系统级全局变量值，如配置文件路径，保证该属性在程序中任何地方都可访问。</p>
<p>注意事项</p>
<ol>
<li>需要设置的是JVM参数而不是program参数；</li>
<li>使用此参数的参数优先级最高，会覆盖项目中配置的此项；</li>
</ol>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-java怎样一行一行的读取字符串/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-java怎样一行一行的读取字符串/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <blockquote>
<p>最近开发中遇到了一个问题,需要一行一行的读取字符串,自己想了想总结了两种方法\</p>
</blockquote>
<h4 id="方法一-使用Scanner类"><a href="#方法一-使用Scanner类" class="headerlink" title="方法一  使用Scanner类"></a>方法一  使用Scanner类</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.Scanner;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        String info =<span class="string">"sdfsdfsdf\n"</span>+<span class="string">"aaaaaa\n"</span>+<span class="string">"bbbbbbbb\n"</span>;</span><br><span class="line">        Scanner scanner = <span class="keyword">new</span> Scanner(info);</span><br><span class="line">        <span class="keyword">while</span>(scanner.hasNext())&#123;</span><br><span class="line">            System.out.println(scanner.nextLine());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>这种方法就是使用了Scanner特性,思路是将带换行符的字符串想象成聪明行进行输入的</p>
</blockquote>
<h4 id="方法二"><a href="#方法二" class="headerlink" title="方法二"></a>方法二</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.io.BufferedReader;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.StringReader;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        BufferedReader reader = <span class="keyword">new</span> BufferedReader(<span class="keyword">new</span> StringReader(<span class="string">"123\n456\n222222\n444"</span>));</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            String line;</span><br><span class="line">            <span class="keyword">while</span>((line=reader.readLine())!=<span class="keyword">null</span>)&#123;</span><br><span class="line">                System.out.println(line);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            reader.close();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>使用Reader进行处理</p>
</blockquote>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-线程安全/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-线程安全/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h3 id="Java语言中的线程安全等级"><a href="#Java语言中的线程安全等级" class="headerlink" title="Java语言中的线程安全等级"></a>Java语言中的线程安全等级</h3><blockquote>
<p>按照线程安全的“安全程度”由强至弱来排序,我们 可以将Java语言中各种操作共享的数据分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。 </p>
</blockquote>
<ol>
<li>不可变：如final关键字 定义的数据不可修改，可靠性最高</li>
<li>绝对线程安全：绝对的线程安全完全满足Brian Goetz给出的线程安全的定义,这个定义其实是很严格的,一个类要达到“不管运行时环境如何,调用者都不需要任何额外的同步措施”通常需要付出很大的,甚至有时候是不切实际的代价。</li>
<li>相对线程安全：相对的线程安全就是我们通常意义上所讲的线程安全,它需要保证对这个对象单独的操作是线程安全的,我们在调用的时候不需要做额外的保障措施,但是对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性，在Java语言中,大部分的线程安全类都属于这种类型,例如Vector、HashTable、Collections的synchronizedCollection()方法包装的集合等</li>
<li>线程兼容：线程兼容是指对象本身并不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全地使用,我们平常说一个类不是线程安全的,绝大多数时候指的是这一种情况</li>
<li>线程对立：线程对立是指无论调用端是否采取了同步措施,都无法在多线程环境中并发使用的代码。由于Java语言天生就具备多线程特性,线程对立这种排斥多线程的代码是很少出现的,而且通常都是有害的,应当尽量避免</li>
</ol>
<h3 id="线程同步的实现方法"><a href="#线程同步的实现方法" class="headerlink" title="线程同步的实现方法"></a>线程同步的实现方法</h3><p><strong>互斥同步</strong>：互斥同步(Mutual Exclusion&amp;Synchronization)是常见的一种并发正确性保障手段。同步是指在多个线程并发访问共享数据时,保证共享数据在同一个时刻只被一个(或者是一些,使用信号量的时候)线程使用。而互斥是实现同步的一种手段,临界区(CriticalSection)、互斥量(Mutex)和信号量(Semaphore)都是主要的互斥实现方式。因此,在这4个字里面,互斥是因,同步是果;互斥是方法,同步是目的。</p>
<blockquote>
<p>引申：jvm执行monitorenter指令时,首先要尝试获取对象的锁。如果这个对象没被锁定,或者当前线程已经拥有了那个对象的锁,把锁的计数器加1,相应的,在执行monitorexit指令时会将锁计数器减1,当计数器为0时,锁就被释放</p>
</blockquote>
<p><strong>java sybcgrinized是重量级锁的原因</strong>：Java的线程是映射到操作系统的原生线程之上的,如果要阻塞或唤醒一个线程,都需要操作系统来帮忙完成,这就需要从用户态转换到核心态中,因此状态转换需要耗费很多的处理器时间。对于代码简单的同步块(如被synchronized修饰的getter()或setter()方法),状态转换消耗的时间有可能比用户代码执行的时间还要长。所以synchronized是Java语言中一个重量级(Heavyweight)的操作,有经验的程序员都会在确实必要的情况下才使用这种操作</p>
<ul>
<li><strong>注意</strong>：互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也称为阻塞同步(Blocking Synchronization)：互斥同步属于一种悲观的并发策略,总是认为只要不去做正确的同步措施(例如加锁),那就肯定会出现问题,无论共享数据是否真的会出现竞争,它都要进行加锁(这里讨论的是概念模型,实际上虚拟机会优化掉很大一部分不必要的加锁)、用户态核心态转换、维护锁计数器和检查是否有被阻塞的线程需要唤醒等操作</li>
</ul>
<p><strong>非阻塞同步</strong>:硬件指令集的发展,出现基于冲突检测的乐观并发策略,通俗地说,就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了;如果共享数据有争用,产生了冲突,那就再采取其他的补偿措施(最常见的补偿措施就是不断地重试,直到成功为止),这种乐观的并发策略的许多实现都不需要把线程挂起,因此这种同步操作称为非阻塞同步(Non-Blocking Synchronization)</p>
<blockquote>
<p>引申非阻塞的实现CAS：CAS指令需要有3个操作数,分别是内存位置(在Java中可以简单理解为变量的内存地址,用V表示)、旧的预期值(用A表示)和新值(用B表示)。CAS指令执行时,当且仅当V处的值符合旧预期值A时,处理器用新值B更新V处的值,否则它就不执行更新,但是无论是否更新了V处的值,都会返回V的旧值,上述的处理过程是一个原子操作。</p>
</blockquote>
<p><strong>JDK1.5之后,Java程序中才可以使用CAS操作</strong>：操作由sun.misc.Unsafe类里面的compareAndSwapInt()和compareAndSwapLong()等几个方法包装提供，我们只能通过其他的JavaAPI来间接使用它,如J.U.C包里面的整数原子类,其中的compareAndSet()和getAndIncrement()等方法都使用了Unsafe类的CAS操作</p>
<ul>
<li><strong>CAS缺点</strong></li>
</ul>
<ol>
<li>ABA问题。因为CAS需要在操作值的时候检查下值有没有发生变化，如果没有发生变化则更新，但是如果一个值原来是A，变成了B，又变成了A，那么使用CAS进行检查时会发现它的值没有发生变化，但是实际上却变化了。ABA问题的解决思路就是使用版本号。在变量前面追加上版本号，每次变量更新的时候把版本号加一，那么A－B－A 就会变成1A-2B－3A。JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用，并且当前标志是否等于预期标志，如果全部相等，则以原子方式将该引用和该标志的值设置为给定的更新值。</li>
<li>循环时间长开销大。自旋CAS如果长时间不成功，会给CPU带来非常大的执行开销。</li>
<li>只能保证一个共享变量的原子操作。当对一个共享变量执行操作时，我们可以使用循环CAS的方式来保证原子操作，但是对多个共享变量操作时，循环CAS就无法保证操作的原子性，这个时候就可以用锁，或者有一个取巧的办法，就是把多个共享变量合并成一个从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性，你可以把多个变量放在一个对象里来进行CAS操作。共享变量来操作。</li>
</ol>
<h3 id="无需线程同步方案"><a href="#无需线程同步方案" class="headerlink" title="无需线程同步方案"></a>无需线程同步方案</h3><p>有些有一些代码天生就是线程安全的,笔者简单地介绍其中的两类：无需同步方案：有些有一些代码天生就是线程安全的,笔者简单地介绍其中的两类</p>
<ol>
<li>可重入代码(Reentrant Code):不依赖存储在堆上的数据和公用的系统资源、用到的状态量都由参数中传入、不调用非可重入的方法</li>
<li>线程本地存储(Thread Local Storage):线程唯一变量，java中的java.lang.ThreadLocal类来实现线程本地存储的功能</li>
</ol>
<blockquote>
<p>ThreadLocal实现原理</p>
</blockquote>
<p>一个线程的Thread对象中都有一个ThreadLocalMap对象,这个对象存储了一组以ThreadLocal.threadLocalHashCode为键,以本地线程变量为值的K-V值对,ThreadLocal对象就是当前线程的ThreadLocalMap的访问入口,每一个ThreadLocal对象都包含了一个独一无二的threadLocalHashCode值,使用这个值就可以在线程K-V值对中找回对应的本地线程变量。</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/element-ui学习笔（一）/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/element-ui学习笔（一）/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-JAAS(Java 认证和授权服务)/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-JAAS(Java 认证和授权服务)/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <blockquote>
<p>之前写过一篇有关java内部安全机制和沙箱的一片文章,那一篇中jvm是基于代码的维度进行权限管理的,但是java在java1.4内置一个JAAS基于用户的权限管理(虽然个人觉得这个东西非常鸡肋,适合单体应用并不适合现在的微服务和分布式框架,因为有个非常坑爹的配置文件-我权限管理都是使用数据库实现的:disappointed_relieved:)</p>
</blockquote>
<h3 id="JAAS的大体组成"><a href="#JAAS的大体组成" class="headerlink" title="JAAS的大体组成"></a>JAAS的大体组成</h3><ol>
<li>客户端通过一个LoginContext对象与JAAS相互作用，这个LoginContext对象提供了一种开发应用程序的方式，它不依赖于底层的认证技术。</li>
<li>LoginContext：是javax.security.auth.login包里的一个类，它描述了用于验证对象(subjects)的方法。</li>
<li>Subject：就是在某个你想去认证和分配访问权限的系统里的一个标识。一个主体(subject)可能是一个用户、一个进程或者是一台机器，它用javax.security.auth.Subject类表示。</li>
<li>java.security.Principal： 由于一个Subject可能涉及多个授权（一个网上银行密码和另一个电子邮件系统），java.security.Principal就被用作在那些关联里的标识。也就是说，该Principal接口是一个能够被用作代表某个实体、公司或者登陆ID的抽象概念。一个Subject可能包含多个Principles. 稍后将有一个示例类实现了这个Principal接口。</li>
<li>LoginContext对象调用负责实现和执行认证的LoginModules。LoginModule接口(在javax.security.auth.spi 包里)必须让认证技术的提供者去实现，并且能够被应用程序指定提供一个特定认证类型。<ul>
<li>LoginContext： 用来读取Configuaration和实例化特定的LoginModules.</li>
<li>Configuaration： 被某个特定的应用程序用作指定认证技术或者LoginModule。因此，不同的LoginModules能够被应用到某个应用程序而不用对这个应用程序做任何的代码修改。</li>
</ul>
</li>
<li>CallbackHandler 安全机制的回调器处理器,用来处理和显示回调的信息<h3 id="一个例子"><a href="#一个例子" class="headerlink" title="一个例子"></a>一个例子</h3></li>
</ol>
<blockquote>
<p>主类:关键的一句第八行-在配置文件example.conf里，实体名”WeatherLogin”就是被MyClient.java用作关联这个实体的名字。这里同时还将一个回调处理程序传给了底层的LoginModule，因此他们能够通过提示用户名/密码同用户进行交流和作用，例如：通过文本或者图形用户接口。一旦LoginContext已经被实例化了，login方法就被调用去登陆.</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// LoginContext：是javax.security.auth.login包里的一个类，它描述了用于验证对象(subjects)的方法。  </span></span><br><span class="line"><span class="comment">// LoginContext对象调用负责实现和执行认证的LoginModules。  </span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyClient</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		LoginContext context = <span class="keyword">null</span>;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			<span class="comment">// 在配置文件example.conf里，实体名"WeatherLogin"就是被MyClient.java用作关联这个实体的名字。</span></span><br><span class="line">			context = <span class="keyword">new</span> LoginContext(<span class="string">"WeatherLogin"</span>, <span class="keyword">new</span> MyCallbackHandler());</span><br><span class="line">		&#125; <span class="keyword">catch</span> (LoginException le) &#123;</span><br><span class="line">			System.err.println(<span class="string">"LoginContext cannot be created. "</span> + le.getMessage());</span><br><span class="line">			System.exit(-<span class="number">1</span>);</span><br><span class="line">		&#125; <span class="keyword">catch</span> (SecurityException se) &#123;</span><br><span class="line">			System.err.println(<span class="string">"LoginContext cannot be created. "</span> + se.getMessage());</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			context.login();<span class="comment">//使用反射调用出自己定义的实现LoginModules的类</span></span><br><span class="line">		&#125; <span class="keyword">catch</span> (LoginException le) &#123;</span><br><span class="line">			System.out.println(<span class="string">"Authentication failed. "</span> + le.getMessage());</span><br><span class="line">			System.exit(-<span class="number">1</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		System.out.println(<span class="string">"authentication succeeded."</span>);</span><br><span class="line">		System.exit(-<span class="number">1</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>回调类:底层安全服务可能要求通过传递单个的callbacks到回调处理程序。基于传递的callbacks，回调处理程序决定怎样去获取和显示信息。</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 一个基于JAAS的应用程序实现了CallbackHandler接口，  </span></span><br><span class="line"><span class="comment">// 因此它能够提示用户去输入特定的认证信息，比如用户名或者密码，或者显示错误或者警告信息。  </span></span><br><span class="line"><span class="comment">// 基于传递的callbacks，回调处理程序决定怎样去获取和显示信息。  </span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyCallbackHandler</span> <span class="keyword">implements</span> <span class="title">CallbackHandler</span> </span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handle</span><span class="params">(Callback[] callbacks)</span> <span class="keyword">throws</span> IOException, UnsupportedCallbackException </span>&#123;</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; callbacks.length; i++) &#123;</span><br><span class="line">			<span class="keyword">if</span> (callbacks[i] <span class="keyword">instanceof</span> NameCallback) &#123;</span><br><span class="line">				NameCallback nc = (NameCallback) callbacks[<span class="number">0</span>];</span><br><span class="line">				System.err.println(nc.getPrompt());</span><br><span class="line">				System.err.flush();</span><br><span class="line">				String name = (<span class="keyword">new</span> BufferedReader(<span class="keyword">new</span> InputStreamReader(System.in))).readLine();</span><br><span class="line">				nc.setName(name);</span><br><span class="line">			&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> UnsupportedCallbackException(callbacks[i], <span class="string">"callback handler not support"</span>);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>Module类:真实的控制操作类</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 以下代码展示了一个LoginModule简单的实现. 这个例子是非常简单的，  </span></span><br><span class="line"><span class="comment">// 因为他仅仅有一个认证字符串和一个Principal（特征） "SunnyDay", 两个都是硬编码。  </span></span><br><span class="line"><span class="comment">// 如果去login，系统将显示"What is the weather like today?", 如果答案是"Sunny", 用户就能通过。  </span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WeatherLoginModule</span> <span class="keyword">implements</span> <span class="title">LoginModule</span> </span>&#123;</span><br><span class="line">	<span class="keyword">private</span> Subject subject;</span><br><span class="line">	<span class="keyword">private</span> ExamplePrincipal entity;</span><br><span class="line">	<span class="keyword">private</span> CallbackHandler callbackhandler;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> NOT = <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> OK = <span class="number">1</span>;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> COMMIT = <span class="number">2</span>;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">int</span> status;</span><br><span class="line">	<span class="comment">// initialize: 这个方法的目的就是用有关的信息去实例化这个LoginModule。</span></span><br><span class="line">	<span class="comment">// 如果login成功，在这个方法里的Subject就被用在存储Principals和Credentials.</span></span><br><span class="line">	<span class="comment">// 注意这个方法有一个能被用作输入认证信息的CallbackHandler。在这个例子里，我没有用CallbackHandler.</span></span><br><span class="line">	<span class="comment">// CallbackHandler是有用的，因为它从被用作特定输入设备里分离了服务提供者。</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">initialize</span><span class="params">(Subject subject, CallbackHandler callbackhandler, Map state, Map options)</span> </span>&#123;</span><br><span class="line">		status = NOT;</span><br><span class="line">		entity = <span class="keyword">null</span>;</span><br><span class="line">		<span class="keyword">this</span>.subject = subject;</span><br><span class="line">		<span class="keyword">this</span>.callbackhandler = callbackhandler;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// login: 请求LoginModule去认证Subject. 注意此时Principal还没有被指定。</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">login</span><span class="params">()</span> <span class="keyword">throws</span> LoginException </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (callbackhandler == <span class="keyword">null</span>) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> LoginException(<span class="string">"No callback handler is available"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		Callback callbacks[] = <span class="keyword">new</span> Callback[<span class="number">1</span>];</span><br><span class="line">		callbacks[<span class="number">0</span>] = <span class="keyword">new</span> NameCallback(<span class="string">"What is the weather like today?"</span>);</span><br><span class="line">		String name = <span class="keyword">null</span>;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			<span class="comment">// 调用 MyCallbackHandler.java 中的 handle 方法进行处理</span></span><br><span class="line">			<span class="comment">// 以读入用户输入的认证信息（如 username）</span></span><br><span class="line">			callbackhandler.handle(callbacks);</span><br><span class="line">			name = ((NameCallback) callbacks[<span class="number">0</span>]).getName();</span><br><span class="line">		&#125; <span class="keyword">catch</span> (java.io.IOException ioe) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> LoginException(ioe.toString());</span><br><span class="line">		&#125; <span class="keyword">catch</span> (UnsupportedCallbackException ce) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> LoginException(<span class="string">"Error: "</span> + ce.getCallback().toString());</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">if</span> (name.equals(<span class="string">"Sunny"</span>)) &#123;</span><br><span class="line">			entity = <span class="keyword">new</span> ExamplePrincipal(<span class="string">"SunnyDay"</span>);</span><br><span class="line">			status = OK;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">		&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// commit: 如果LoginContext的认证全部成功就调用这个方法。</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">commit</span><span class="params">()</span> <span class="keyword">throws</span> LoginException </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (status == NOT) &#123;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">if</span> (subject == <span class="keyword">null</span>) &#123;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		Set entities = subject.getPrincipals();</span><br><span class="line">		<span class="keyword">if</span> (!entities.contains(entity)) &#123;</span><br><span class="line">			entities.add(entity);</span><br><span class="line">		&#125;</span><br><span class="line">		status = COMMIT;</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// abort: 通知其他LoginModule供应者或LoginModule模型认证已经失败了。整个login将失败。</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">abort</span><span class="params">()</span> <span class="keyword">throws</span> LoginException </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> ((subject != <span class="keyword">null</span>) &amp;&amp; (entity != <span class="keyword">null</span>)) &#123;</span><br><span class="line">			Set entities = subject.getPrincipals();</span><br><span class="line">			<span class="keyword">if</span> (entities.contains(entity)) &#123;</span><br><span class="line">				entities.remove(entity);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		subject = <span class="keyword">null</span>;</span><br><span class="line">		entity = <span class="keyword">null</span>;</span><br><span class="line">		status = NOT;</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// logout: 通过从Subject里移除Principals和Credentials注销Subject。</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">logout</span><span class="params">()</span> <span class="keyword">throws</span> LoginException </span>&#123;</span><br><span class="line">		subject.getPrincipals().remove(entity);</span><br><span class="line">		status = NOT;</span><br><span class="line">		subject = <span class="keyword">null</span>;</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>Principal : Principal接口的一个实现。</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ExamplePrincipal 展示了Principal（主体特征）接口的一个实现。   </span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ExamplePrincipal</span> <span class="keyword">implements</span> <span class="title">Principal</span> </span>&#123;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">final</span> String name;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="title">ExamplePrincipal</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (name == <span class="keyword">null</span>) &#123;</span><br><span class="line">			<span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"Null name"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">this</span>.name = name;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> name;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="string">"ExamplePrinciapl: "</span> + name;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object obj)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (obj == <span class="keyword">null</span>)</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		<span class="keyword">if</span> (obj == <span class="keyword">this</span>)</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">		<span class="keyword">if</span> (!(obj <span class="keyword">instanceof</span> ExamplePrincipal))</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		ExamplePrincipal another = (ExamplePrincipal) obj;</span><br><span class="line">		<span class="keyword">return</span> name.equals(another.getName());</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hasCode</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> name.hashCode();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="配置文件设置"><a href="#配置文件设置" class="headerlink" title="配置文件设置"></a>配置文件设置</h3><blockquote>
<p>LoginContext通过读取Configuration去决定那个LoginModule将被使用。</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">WeatherLogin</span><br><span class="line">&#123;</span><br><span class="line">    com.kys.WeatherLoginModule required;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>使用下面的命令（指定了login配置文件）运行客户端.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">prompt&gt; java -Djava.security.auth.login.config=example.conf MyClient</span><br></pre></td></tr></table></figure>
<blockquote>
<p>引申:如果开启了安全模式java -Djava.security.manager,需要指定安全策略的</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">grant codebase <span class="string">"file:./*"</span></span><br><span class="line">&#123;</span><br><span class="line">  permission javax.security.auth.AuthPermission <span class="string">"createLoginContext"</span>;</span><br><span class="line">  permission javax.security.auth.AuthPermission <span class="string">"modifyPrincipals"</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>运行如下的命令运行<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -Djava.security.manager -Djava.security.policy==policy.txt -Djava.security.auth.login.config==example.conf MyClient</span><br></pre></td></tr></table></figure></p>
<blockquote>
<p>结束语: 看看就好了,知道是个啥就行了,基本上用不上</p>
</blockquote>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/go语言学习笔记（一)/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/go语言学习笔记（一)/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h3 id="go-变量声明"><a href="#go-变量声明" class="headerlink" title="go 变量声明"></a>go 变量声明</h3><p>第一种，指定变量类型，声明后若不赋值，使用默认值。<br><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> v_name v_type</span><br></pre></td></tr></table></figure></p>
<p>第二种，根据值自行判定变量类型。<br><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> v_name = value</span><br></pre></td></tr></table></figure></p>
<p>第三种，省略var, 注意 :=左侧的变量不应该是已经声明过的，否则会导致编译错误。<br><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">v_name := value</span><br><span class="line"><span class="comment">// 例如</span></span><br><span class="line"><span class="keyword">var</span> a <span class="keyword">int</span> = <span class="number">10</span></span><br><span class="line"><span class="keyword">var</span> b = <span class="number">10</span></span><br><span class="line">c : = <span class="number">10</span></span><br></pre></td></tr></table></figure></p>
<p>###go多变量声明</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"><span class="keyword">var</span> x, y <span class="keyword">int</span></span><br><span class="line"><span class="keyword">var</span> ( <span class="comment">//这种只能出现在全局变量中，函数体内不支持</span></span><br><span class="line">	a <span class="keyword">int</span></span><br><span class="line">	b <span class="keyword">bool</span></span><br><span class="line">)</span><br><span class="line"><span class="keyword">var</span> c, d <span class="keyword">int</span> = <span class="number">1</span>, <span class="number">2</span></span><br><span class="line"><span class="keyword">var</span> e, f = <span class="number">123</span>, <span class="string">"hello"</span><span class="comment">//类型可以不同</span></span><br><span class="line"><span class="comment">//这种不带声明格式的只能在函数体中出现</span></span><br><span class="line"><span class="comment">//g, h := 123, "hello"</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	x = <span class="number">123</span></span><br><span class="line">	y = <span class="number">22</span></span><br><span class="line">	g, h := <span class="number">123</span>, <span class="string">"hello"</span></span><br><span class="line">	<span class="built_in">println</span>(x, y, a, b, c, d, e, f, g, h)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行结果</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0 0 0 false 1 2 123 hello 123 hello</span><br></pre></td></tr></table></figure>
<p>注意：在多赋值的时候如果想要省略掉一个可以使用这种方法 <em>,b=12,333 ,</em>在go语言中有只读的作用，使用这个方法可以灵活的处理</p>
<h3 id="go-引用取值"><a href="#go-引用取值" class="headerlink" title="go 引用取值"></a>go 引用取值</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	<span class="keyword">var</span> a = <span class="number">123</span></span><br><span class="line">	<span class="keyword">var</span> b *<span class="keyword">int</span> = &amp;a</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里使用了地址操作符所以 b和a 其实是一个东西</p>
<blockquote>
<p>注意 &amp;符号的意思是对变量取地址，如：变量a的地址是&amp;a ，<em> 符号的意思是对指针取值，如: </em>&amp;a，就是a变量所在地址的值，当然也就是a的值了</p>
</blockquote>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/dubbo深入（三）配置参考/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/dubbo深入（三）配置参考/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="深入dubbo（三）配置参考"><a href="#深入dubbo（三）配置参考" class="headerlink" title="深入dubbo（三）配置参考"></a>深入dubbo（三）配置参考</h2><p><strong>配置项分为三大类</strong>：服务发现：表示该配置项用于服务的注册与发现，目的是让消费方找到提供方。服务治理：表示该配置项用于治理服务间的关系，或为开发测试提供便利条件。性能调优：表示该配置项用于调优性能，不同的选项对性能会产生影响。</p>
<p><strong>注意</strong>：只有 group，interface，version 是服务的匹配条件，三者决定是不是同一个服务，其它配置项均为调优和治理参数。</p>
<h3 id="启动时检查参数-check"><a href="#启动时检查参数-check" class="headerlink" title="启动时检查参数 check"></a>启动时检查参数 check</h3><blockquote>
<p>使用标签 reference consumer registry</p>
</blockquote>
<p>xml配置法</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">check</span>=<span class="string">"false"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:consumer</span> <span class="attr">check</span>=<span class="string">"false"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">check</span>=<span class="string">"false"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>配置文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">dubbo.reference.com.foo.BarService.check=false</span><br><span class="line">dubbo.reference.check=false</span><br><span class="line">dubbo.consumer.check=false</span><br><span class="line">dubbo.registry.check=false</span><br></pre></td></tr></table></figure>
<p>Dubbo 缺省会在启动时检查依赖的服务是否可用，可以通过 check=”false” 关闭检查（有些服务不关心，或者出现了循环依赖，必须有一方先启动， 比如Spring 容器是懒加载的，或者通过 API 编程延迟引用服务）</p>
<h3 id="集群容错配置"><a href="#集群容错配置" class="headerlink" title="集群容错配置"></a>集群容错配置</h3><ol>
<li>默认Failover Cluster</li>
</ol>
<p>失败自动切换，当出现失败，重试其它服务器 1。通常用于读操作，但重试会带来更长延迟。可通过 retries=”2″ 来设置重试次数(不含第一次)。配置如下</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">retries</span>=<span class="string">"2"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">retries</span>=<span class="string">"2"</span> /&gt;</span></span><br><span class="line"> </span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findFoo"</span> <span class="attr">retries</span>=<span class="string">"2"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:reference</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol start="2">
<li>Failfast Cluster</li>
</ol>
<p>快速失败，只发起一次调用，失败立即报错。通常用于非幂等性的写操作，比如新增记录。</p>
<ol start="3">
<li>Failsafe Cluster</li>
</ol>
<p>失败安全，出现异常时，直接忽略。通常用于写入审计日志等操作。</p>
<ol start="4">
<li>Failback Cluster</li>
</ol>
<p>失败自动恢复，后台记录失败请求，定时重发。通常用于消息通知操作。</p>
<ol start="5">
<li>Forking Cluster</li>
</ol>
<p>并行调用多个服务器，只要一个成功即返回。通常用于实时性要求较高的读操作，但需要浪费更多服务资源。可通过 forks=”2″ 来设置最大并行数。</p>
<ol start="6">
<li><p>Broadcast Cluster<br>广播调用所有提供者，逐个调用，任意一台报错则报错 2。通常用于通知所有提供者更新缓存或日志等本地资源信息。</p>
</li>
<li><p>集群模式配置<br>以上六种按照以下示例在服务提供方和消费方配置集群模式</p>
</li>
</ol>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">cluster</span>=<span class="string">"failsafe"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">cluster</span>=<span class="string">"failsafe"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="负载均衡配置"><a href="#负载均衡配置" class="headerlink" title="负载均衡配置"></a>负载均衡配置</h3><ol>
<li>Random LoadBalance随机，按权重设置随机概率。在一个截面上碰撞的概率高，但调用量越大分布越均匀，而且按概率使用权重后也比较均匀，有利于动态调整提供者权重。</li>
<li>RoundRobin LoadBalance轮循，按公约后的权重设置轮循比率。存在慢的提供者累积请求的问题，比如：第二台机器很慢，但没挂，当请求调到第二台时就卡在那，久而久之，所有请求都卡在调到第二台上。</li>
<li>LeastActive LoadBalance最少活跃调用数，相同活跃数的随机，活跃数指调用前后计数差。使慢的提供者收到更少请求，因为越慢的提供者的调用前后计数差会越大。</li>
</ol>
<blockquote>
<p>ConsistentHash LoadBalance一致性 Hash，相同参数的请求总是发到同一提供者。</p>
</blockquote>
<blockquote>
<p>当某一台提供者挂时，原本发往该提供者的请求，基于虚拟节点，平摊到其它提供者，不会引起剧烈变动。</p>
</blockquote>
<ul>
<li>缺省只对第一个参数 Hash，如果要修改，请配置 &lt;dubbo:parameter key=”hash.arguments” value=”0,1″ /&gt;</li>
<li>缺省用 160 份虚拟节点，如果要修改，请配置 &lt;dubbo:parameter key=”hash.nodes” value=”320″ /&gt;</li>
</ul>
<p><strong>配置方法</strong></p>
<p><strong>服务端服务级别</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"..."</span> <span class="attr">loadbalance</span>=<span class="string">"roundrobin"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>客户端服务级别</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"..."</span> <span class="attr">loadbalance</span>=<span class="string">"roundrobin"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>服务端方法级别</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"..."</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"..."</span> <span class="attr">loadbalance</span>=<span class="string">"roundrobin"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:service</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>客户端方法级别</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"..."</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"..."</span> <span class="attr">loadbalance</span>=<span class="string">"roundrobin"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:reference</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="线程池"><a href="#线程池" class="headerlink" title="线程池"></a>线程池</h3><p>对于Dubbo的服务提供者，主要有两种线程池，一种是IO处理线程池，另一种是服务调用线程池。而作为IO处理线程池，由于Dubbo基于Mina、Grizzly和Netty框架做IO组件，IO线程池都是基于这些框架来配置，比如Netty中的boss和worker线程池，Dubbo选择的是“无边界”的CachedThreadPool，这意味着对所有服务请求先做到“来者不拒”，但它进一步限制了IO处理的线程数，默认是核数+1</p>
<p>如果事件处理的逻辑能迅速完成，并且不会发起新的 IO 请求，比如只是在内存中记个标识，则直接在 IO 线程上处理更快，如果事件处理逻辑较慢，或者需要发起新的IO请求，比如需要查询数据库，则必须派发到IO线程池中</p>
<p><img src="blogimg/dubbo/6.jpg" alt=""></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"dubbo"</span> <span class="attr">dispatcher</span>=<span class="string">"all"</span> <span class="attr">threadpool</span>=<span class="string">"fixed"</span> <span class="attr">threads</span>=<span class="string">"100"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>Dispatcher</p>
<ul>
<li>all 所有消息都派发到线程池，包括请求，响应，连接事件，断开事件，心跳等。</li>
<li>direct 所有消息都不派发到线程池，全部在 IO 线程上直接执行。</li>
<li>message 只有请求响应消息派发到线程池，其它连接断开事件，心跳等消息，直接在 IO 线程上执行。</li>
<li>execution 只请求消息派发到线程池，不含响应，响应和其它连接断开事件，心跳等消息，直接在 IO 线程上执行。</li>
<li>connection 在 IO 线程上，将连接断开事件放入队列，有序逐个执行，其它消息派发到线程池。</li>
</ul>
<p>ThreadPool</p>
<ul>
<li>fixed 固定大小线程池，启动时建立线程，不关闭，一直持有。(缺省)</li>
<li>cached 缓存线程池，空闲一分钟自动删除，需要时重建。</li>
<li>limited 可伸缩线程池，但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。</li>
</ul>
<h3 id="直接链接和只订阅模式"><a href="#直接链接和只订阅模式" class="headerlink" title="直接链接和只订阅模式"></a>直接链接和只订阅模式</h3><p>在开发及测试环境下，经常需要绕过注册中心，只测试指定服务提供者，这时候可能需要点对点直连</p>
<p>点对点，可在 <a href="dubbo:reference" target="_blank" rel="noopener">dubbo:reference</a> 中配置 url 指向提供者，将绕过注册中心，多个地址用分号隔开</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">id</span>=<span class="string">"xxxService"</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.xxx.XxxService"</span> <span class="attr">url</span>=<span class="string">"dubbo://localhost:20890"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>注意：为了避免复杂化线上环境，不要在线上使用这个功能，只应在测试阶段使用。</p>
<p>只订阅模式：一般和直连连用，解决在测试环境下注册中心共用可能导致，线上业务受到影响的问题</p>
<p><img src="blogimg/dubbo/7.jpg" alt=""></p>
<p>禁用注册配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">address</span>=<span class="string">"10.20.153.10:9090"</span> <span class="attr">register</span>=<span class="string">"false"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">address</span>=<span class="string">"10.20.153.10:9090?register=false"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="注册到指定的服务器"><a href="#注册到指定的服务器" class="headerlink" title="注册到指定的服务器"></a>注册到指定的服务器</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">id</span>=<span class="string">"hzRegistry"</span> <span class="attr">address</span>=<span class="string">"10.20.153.10:9090"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">id</span>=<span class="string">"qdRegistry"</span> <span class="attr">address</span>=<span class="string">"10.20.141.150:9090"</span> <span class="attr">subscribe</span>=<span class="string">"false"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="使用多个协议和使用多个注册中心"><a href="#使用多个协议和使用多个注册中心" class="headerlink" title="使用多个协议和使用多个注册中心"></a>使用多个协议和使用多个注册中心</h3><p>Dubbo 允许配置多协议，在不同服务上支持不同协议或者同一服务上同时支持多种协议。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:dubbo</span>=<span class="string">"http://code.alibabatech.com/schema/dubbo"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:application</span> <span class="attr">name</span>=<span class="string">"world"</span>  /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">id</span>=<span class="string">"registry"</span> <span class="attr">address</span>=<span class="string">"10.20.141.150:9090"</span> <span class="attr">username</span>=<span class="string">"admin"</span> <span class="attr">password</span>=<span class="string">"hello1234"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 多协议配置 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"dubbo"</span> <span class="attr">port</span>=<span class="string">"20880"</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"rmi"</span> <span class="attr">port</span>=<span class="string">"1099"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 使用dubbo协议暴露服务 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.hello.api.HelloService"</span> <span class="attr">version</span>=<span class="string">"1.0.0"</span> <span class="attr">ref</span>=<span class="string">"helloService"</span> <span class="attr">protocol</span>=<span class="string">"dubbo"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 使用rmi协议暴露服务 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.hello.api.DemoService"</span> <span class="attr">version</span>=<span class="string">"1.0.0"</span> <span class="attr">ref</span>=<span class="string">"demoService"</span> <span class="attr">protocol</span>=<span class="string">"rmi"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--使用多个协议进行配置--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">id</span>=<span class="string">"helloService"</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.hello.api.HelloService"</span> <span class="attr">version</span>=<span class="string">"1.0.0"</span> <span class="attr">protocol</span>=<span class="string">"dubbo,hessian"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>Dubbo 支持同一服务向多注册中心同时注册，或者不同服务分别注册到不同的注册中心上去，甚至可以同时引用注册在不同注册中心上的同名服务。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:dubbo</span>=<span class="string">"http://code.alibabatech.com/schema/dubbo"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:application</span> <span class="attr">name</span>=<span class="string">"world"</span>  /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 多注册中心配置 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">id</span>=<span class="string">"hangzhouRegistry"</span> <span class="attr">address</span>=<span class="string">"10.20.141.150:9090"</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">id</span>=<span class="string">"qingdaoRegistry"</span> <span class="attr">address</span>=<span class="string">"10.20.141.151:9010"</span> <span class="attr">default</span>=<span class="string">"false"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 向多个注册中心注册 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.hello.api.HelloService"</span> <span class="attr">version</span>=<span class="string">"1.0.0"</span> <span class="attr">ref</span>=<span class="string">"helloService"</span> <span class="attr">registry</span>=<span class="string">"hangzhouRegistry,qingdaoRegistry"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--使用不同的注册中心--&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 向中文站注册中心注册 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.hello.api.HelloService"</span> <span class="attr">version</span>=<span class="string">"1.0.0"</span> <span class="attr">ref</span>=<span class="string">"helloService"</span> <span class="attr">registry</span>=<span class="string">"chinaRegistry"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 向国际站注册中心注册 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.hello.api.DemoService"</span> <span class="attr">version</span>=<span class="string">"1.0.0"</span> <span class="attr">ref</span>=<span class="string">"demoService"</span> <span class="attr">registry</span>=<span class="string">"intlRegistry"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>同时链接到多个不同的注册中心    service 省略 registry属性将自动的使用默认配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:dubbo</span>=<span class="string">"http://code.alibabatech.com/schema/dubbo"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:application</span> <span class="attr">name</span>=<span class="string">"world"</span>  /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 多注册中心配置，竖号分隔表示同时连接多个不同注册中心，同一注册中心的多个集群地址用逗号分隔 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">address</span>=<span class="string">"10.20.141.150:9090|10.20.154.177:9010"</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 引用服务 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">id</span>=<span class="string">"helloService"</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.hello.api.HelloService"</span> <span class="attr">version</span>=<span class="string">"1.0.0"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="分组聚合"><a href="#分组聚合" class="headerlink" title="分组聚合"></a>分组聚合</h3><p>按组合并返回结果 ，比如菜单服务，接口一样，但有多种实现，用group区分，现在消费方需从每种group中调用一次返回结果，合并结果返回，这样就可以实现聚合菜单项。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--合并指定的分组--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.xxx.MenuService"</span> <span class="attr">group</span>=<span class="string">"*"</span> <span class="attr">merger</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.xxx.MenuService"</span> <span class="attr">group</span>=<span class="string">"aaa,bbb"</span> <span class="attr">merger</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="comment">&lt;!--指定方法的结果进行整合--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.xxx.MenuService"</span> <span class="attr">group</span>=<span class="string">"*"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"getMenuItems"</span> <span class="attr">merger</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:service</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--指定某一个方法不进行整合--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.xxx.MenuService"</span> <span class="attr">group</span>=<span class="string">"*"</span> <span class="attr">merger</span>=<span class="string">"true"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"getMenuItems"</span> <span class="attr">merger</span>=<span class="string">"false"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:service</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>注意：dubbo只有默认的四种组合，list set map array ，所以返回的结果值必须要是以上几种类型</p>
<h3 id="结果缓存"><a href="#结果缓存" class="headerlink" title="结果缓存"></a>结果缓存</h3><p>结果缓存 ，用于加速热门数据的访问速度，Dubbo 提供声明式缓存，以减少用户加缓存的工作量 2。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">cache</span>=<span class="string">"lru"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findBar"</span> <span class="attr">cache</span>=<span class="string">"lru"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:reference</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="回声测试"><a href="#回声测试" class="headerlink" title="回声测试"></a>回声测试</h3><p>回声测试用于检测服务是否可用，回声测试按照正常请求流程执行，能够测试整个调用是否通畅，可用于监控。</p>
<p>所有服务自动实现 EchoService 接口，只需将任意服务引用强制转型为 EchoService，即可使用。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">id</span>=<span class="string">"memberService"</span> <span class="attr">interface</span>=<span class="string">"com.xxx.MemberService"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
 <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 远程服务引用</span></span><br><span class="line">MemberService memberService = ctx.getBean(<span class="string">"memberService"</span>); </span><br><span class="line">EchoService echoService = (EchoService) memberService; <span class="comment">// 强制转型为EchoService</span></span><br><span class="line"><span class="comment">// 回声测试可用性</span></span><br><span class="line">String status = echoService.$echo(<span class="string">"OK"</span>); </span><br><span class="line"><span class="keyword">assert</span>(status.equals(<span class="string">"OK"</span>));</span><br></pre></td></tr></table></figure>
<h3 id="上下文信息获取和从客户端向服务端传递参数"><a href="#上下文信息获取和从客户端向服务端传递参数" class="headerlink" title="上下文信息获取和从客户端向服务端传递参数"></a>上下文信息获取和从客户端向服务端传递参数</h3><p>上下文中存放的是当前调用过程中所需的环境信息。所有配置信息都将转换为 URL 的参数</p>
<p>RpcContext 是一个 ThreadLocal 的临时状态记录器，当接收到 RPC 请求，或发起 RPC 请求时，RpcContext 的状态都会变化。比如：A 调 B，B 再调 C，则 B 机器上，在 B 调 C 之前，RpcContext 记录的是 A 调 B 的信息，在 B 调 C 之后，RpcContext 记录的是 B 调 C 的信息。</p>
<blockquote>
<p>对于服务的消费方，注意只有在使用rpc调用之后才状态会发生改变</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 远程调用</span></span><br><span class="line">xxxService.xxx();</span><br><span class="line"><span class="comment">// 本端是否为消费端，这里会返回true</span></span><br><span class="line"><span class="keyword">boolean</span> isConsumerSide = RpcContext.getContext().isConsumerSide();</span><br><span class="line"><span class="comment">// 获取最后一次调用的提供方IP地址</span></span><br><span class="line">String serverIP = RpcContext.getContext().getRemoteHost();</span><br><span class="line"><span class="comment">// 获取当前服务配置信息，所有配置信息都将转换为URL的参数</span></span><br><span class="line">String application = RpcContext.getContext().getUrl().getParameter(<span class="string">"application"</span>);</span><br><span class="line"><span class="comment">// 注意：每发起RPC调用，上下文状态会变化</span></span><br><span class="line">yyyService.yyy();</span><br></pre></td></tr></table></figure>
<blockquote>
<p>服务提供方，注意只有在服务类中进行注册才能坚挺到数据</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">XxxServiceImpl</span> <span class="keyword">implements</span> <span class="title">XxxService</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">xxx</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 本端是否为提供端，这里会返回true</span></span><br><span class="line">        <span class="keyword">boolean</span> isProviderSide = RpcContext.getContext().isProviderSide();</span><br><span class="line">        <span class="comment">// 获取调用方IP地址</span></span><br><span class="line">        String clientIP = RpcContext.getContext().getRemoteHost();</span><br><span class="line">        <span class="comment">// 获取当前服务配置信息，所有配置信息都将转换为URL的参数</span></span><br><span class="line">        String application = RpcContext.getContext().getUrl().getParameter(<span class="string">"application"</span>);</span><br><span class="line">        <span class="comment">// 注意：每发起RPC调用，上下文状态会变化</span></span><br><span class="line">        yyyService.yyy();</span><br><span class="line">        <span class="comment">// 此时本端变成消费端，这里会返回false</span></span><br><span class="line">        <span class="keyword">boolean</span> isProviderSide = RpcContext.getContext().isProviderSide();</span><br><span class="line">    &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="参数传递流程图"><a href="#参数传递流程图" class="headerlink" title="参数传递流程图"></a>参数传递流程图</h3><p><img src="blogimg/dubbo/6.png" alt=""></p>
<blockquote>
<p>在服务消费方端设置隐式参数</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">RpcContext.getContext().setAttachment(<span class="string">"index"</span>, <span class="string">"1"</span>); <span class="comment">// 隐式传参，后面的远程调用都会隐式将这些参数发送到服务器端，类似cookie，用于框架集成，不建议常规业务使用</span></span><br><span class="line">xxxService.xxx(); <span class="comment">// 远程调用</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>在服务提供方端获取隐式参数</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">XxxServiceImpl</span> <span class="keyword">implements</span> <span class="title">XxxService</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">xxx</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 获取客户端隐式传入的参数，用于框架集成，不建议常规业务使用</span></span><br><span class="line">        String index = RpcContext.getContext().getAttachment(<span class="string">"index"</span>); </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="异步调用"><a href="#异步调用" class="headerlink" title="异步调用"></a>异步调用</h3><p><img src="blogimg/dubbo/8.jpg" alt=""></p>
<p><strong>注意</strong>:要在客户端进行配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">id</span>=<span class="string">"fooService"</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.foo.FooService"</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findFoo"</span> <span class="attr">async</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:reference</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">id</span>=<span class="string">"barService"</span> <span class="attr">interface</span>=<span class="string">"com.alibaba.bar.BarService"</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findBar"</span> <span class="attr">async</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:reference</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>调用代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 此调用会立即返回null</span></span><br><span class="line">fooService.findFoo(fooId);</span><br><span class="line"><span class="comment">// 拿到调用的Future引用，当结果返回后，会被通知和设置到此Future</span></span><br><span class="line">Future&lt;Foo&gt; fooFuture = RpcContext.getContext().getFuture(); </span><br><span class="line"><span class="comment">// 此调用会立即返回null</span></span><br><span class="line">barService.findBar(barId);</span><br><span class="line"><span class="comment">// 拿到调用的Future引用，当结果返回后，会被通知和设置到此Future</span></span><br><span class="line">Future&lt;Bar&gt; barFuture = RpcContext.getContext().getFuture(); </span><br><span class="line"><span class="comment">// 此时findFoo和findBar的请求同时在执行，客户端不需要启动多线程来支持并行，而是借助NIO的非阻塞完成</span></span><br><span class="line"><span class="comment">// 如果foo已返回，直接拿到返回值，否则线程wait住，等待foo返回后，线程会被notify唤醒</span></span><br><span class="line">Foo foo = fooFuture.get(); </span><br><span class="line"><span class="comment">// 同理等待bar返回</span></span><br><span class="line">Bar bar = barFuture.get(); </span><br><span class="line"><span class="comment">// 如果foo需要5秒返回，bar需要6秒返回，实际只需等6秒，即可获取到foo和bar，进行接下来的处理。</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>你也可以设置是否等待消息发出</p>
</blockquote>
<ul>
<li>sent=”true” 等待消息发出，消息发送失败将抛出异常。</li>
<li>sent=”false” 不等待消息发出，将消息放入 IO 队列，即刻返回。</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findFoo"</span> <span class="attr">async</span>=<span class="string">"true"</span> <span class="attr">sent</span>=<span class="string">"true"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>如果你只是想异步，完全忽略返回值，可以配置 return=”false”，以减少 Future 对象的创建和管理成本</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findFoo"</span> <span class="attr">async</span>=<span class="string">"true"</span> <span class="attr">return</span>=<span class="string">"false"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>注意</strong>:如果服务端长时间进行堵塞，客户端可能会发生超时问题，所以有时可能要在前台设置超时时间</p>
<p><strong>坑点</strong>：dubbo的一部调用会延续一次，也就是说a一部调用b，b同步调用c，其实上b还是异步调用c</p>
<h3 id="dubbo内置调用拦截"><a href="#dubbo内置调用拦截" class="headerlink" title="dubbo内置调用拦截"></a>dubbo内置调用拦截</h3><p>在本地拦截方法调用过程中的 before after throww  return过程  其实相当于为dubbo远程调用的处理工程提供了统一的模板 （注意dubbo的哲学思想——提供一个公共的api，使用api进行相互的调用）</p>
<p>服务端配置方法</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">stub</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">stub</span>=<span class="string">"com.foo.BarServiceStub"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>公共api提供，Barservice接口的Stub实现</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.foo;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BarServiceStub</span> <span class="keyword">implements</span> <span class="title">BarService</span> </span>&#123; </span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> BarService barService;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 构造函数传入真正的远程代理对象</span></span><br><span class="line">    <span class="keyword">public</span> (BarService barService) &#123;</span><br><span class="line">        <span class="keyword">this</span>.barService = barService;</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">sayHello</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 此代码在客户端执行, 你可以在客户端做ThreadLocal本地缓存，或预先验证参数是否合法，等等</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> barService.sayHello(name);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            <span class="comment">// 你可以容错，可以做任何AOP拦截事项</span></span><br><span class="line">            <span class="keyword">return</span> <span class="string">"容错数据"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>本地伪装  通常用于服务降级，比如某验权服务，当服务提供方全部挂掉后，客户端不抛出异常，而是通过 Mock 数据返回授权失败。</p>
<p>服务端配置方法</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">mock</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">mock</span>=<span class="string">"com.foo.BarServiceMock"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>公共api提供接口的Mock实现</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.foo;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BarServiceMock</span> <span class="keyword">implements</span> <span class="title">BarService</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">sayHello</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 你可以伪造容错数据，此方法只在出现RpcException时被执行</span></span><br><span class="line">        <span class="keyword">return</span> <span class="string">"容错数据"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这样当发生调用异常的时候，将会调用上面Mock类相应的方法，使用调用</p>
<h3 id="服务懒链接和延迟暴露和对应调用"><a href="#服务懒链接和延迟暴露和对应调用" class="headerlink" title="服务懒链接和延迟暴露和对应调用"></a>服务懒链接和延迟暴露和对应调用</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">delay</span>=<span class="string">"5000"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">delay</span>=<span class="string">"-1"</span> /&gt;</span> 等到spring框架初始化完成后再进行调用</span><br></pre></td></tr></table></figure>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"dubbo"</span> <span class="attr">lazy</span>=<span class="string">"true"</span> /&gt;</span>当调用发起后再进行相应的链接</span><br></pre></td></tr></table></figure>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"dubbo"</span> <span class="attr">sticky</span>=<span class="string">"true"</span> /&gt;</span>  尽可能让调用者一直调用相同的服务器</span><br></pre></td></tr></table></figure>
<h3 id="并发控制和链接控制"><a href="#并发控制和链接控制" class="headerlink" title="并发控制和链接控制"></a>并发控制和链接控制</h3><p>服务端和客户端并发控制配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">限制 com.foo.BarService 的每个方法，服务器端并发执行（或占用线程池线程数）不能超过 10 个</span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">executes</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line">限制 com.foo.BarService 的 sayHello 方法，服务器端并发执行（或占用线程池线程数）不能超过 10 个：</span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"sayHello"</span> <span class="attr">executes</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:service</span>&gt;</span></span><br><span class="line">限制 com.foo.BarService 的每个方法，每客户端并发执行（或占用连接的请求数）不能超过 10 个：</span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">actives</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line">或</span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">actives</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line">限制 com.foo.BarService 的 sayHello 方法，每客户端并发执行（或占用连接的请求数）不能超过 10 个：</span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"sayHello"</span> <span class="attr">actives</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:service</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"sayHello"</span> <span class="attr">actives</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:service</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>注意</strong>：服务端的并发执行参数控制只能在服务端配置，配置参数executes  ， 客户端 并发执行参数，可在服务端或者客户端配置 参数active 客户端优先</p>
<p>服务端链接控制</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:provider</span> <span class="attr">protocol</span>=<span class="string">"dubbo"</span> <span class="attr">accepts</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"dubbo"</span> <span class="attr">accepts</span>=<span class="string">"10"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>客户端链接控制</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">connections</span>=<span class="string">"10"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:service</span> <span class="attr">interface</span>=<span class="string">"com.foo.BarService"</span> <span class="attr">connections</span>=<span class="string">"10"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="一个概念：范化引用"><a href="#一个概念：范化引用" class="headerlink" title="一个概念：范化引用"></a>一个概念：范化引用</h3><p>泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况，参数及返回值中的所有 POJO 均用 Map 表示，通常用于框架集成，</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/dubbo深入（二）注册中心/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/dubbo深入（二）注册中心/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="深入dubbo（二）注册中心"><a href="#深入dubbo（二）注册中心" class="headerlink" title="深入dubbo（二）注册中心"></a>深入dubbo（二）注册中心</h2><p>注册中心只要解决的问题就是，服务端和消费端的相互发现的问题，断开重链接的问题</p>
<h3 id="基于广播实现注册的Multicast-注册中心"><a href="#基于广播实现注册的Multicast-注册中心" class="headerlink" title="基于广播实现注册的Multicast 注册中心"></a>基于广播实现注册的Multicast 注册中心</h3><p>Multicast 注册中心不需要启动任何中心节点，只要广播地址一样，就可以互相发现。</p>
<p><img src="blogimg/dubbo/3.jpg" alt=""></p>
<ol>
<li>提供方启动时广播自己的地址</li>
<li>消费方启动时广播订阅请求</li>
<li>提供方收到订阅请求时，单播自己的地址给订阅者，如果设置了 unicast=false，则广播给订阅者</li>
<li>消费方收到提供方地址时，连接该地址进行 RPC 调用。</li>
</ol>
<p>配置方法</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">address</span>=<span class="string">"multicast://224.5.6.7:1234"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">protocol</span>=<span class="string">"multicast"</span> <span class="attr">address</span>=<span class="string">"224.5.6.7:1234"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>为了减少广播量，Dubbo 缺省使用单播发送提供者地址信息给消费者，如果一个机器上同时启了多个消费者进程，消费者需声明 unicast=false，否则只会有一个消费者能收到消息</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">address</span>=<span class="string">"multicast://224.5.6.7:1234?unicast=false"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">protocol</span>=<span class="string">"multicast"</span> <span class="attr">address</span>=<span class="string">"224.5.6.7:1234"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:parameter</span> <span class="attr">key</span>=<span class="string">"unicast"</span> <span class="attr">value</span>=<span class="string">"false"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:registry</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>注意问题</strong>,hostname需要为本地的ip地址（不能是127.0.0.1），ubuntu系统需要修改hosts文件</p>
<h3 id="使用基于zookeeper的注册中心"><a href="#使用基于zookeeper的注册中心" class="headerlink" title="使用基于zookeeper的注册中心"></a>使用基于zookeeper的注册中心</h3><p>注册依赖于zookeeper底层树实现</p>
<p><img src="blogimg/dubbo/4.jpg" alt=""></p>
<p><strong>流程说明：</strong></p>
<ol>
<li>服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址</li>
<li>服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址</li>
<li>监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址。</li>
</ol>
<p><strong>功能特点：</strong></p>
<ol>
<li>提供者出现断电等异常停机时，注册中心能自动删除提供者信息，注册中心重启时，能自动恢复注册数据，以及订阅请求，会话过期时，能自动恢复注册数据，以及订阅请求</li>
<li>&lt;dubbo:registry check=“false“ /&gt; 时，记录失败注册和订阅请求，后台定时重试</li>
<li>通过 &lt;dubbo:registry username=“admin“ password=“1234“ /&gt; 设置 zookeeper 登录信息</li>
<li>&lt;dubbo:registry group=“dubbo“ /&gt; 设置 zookeeper 的根节点，不设置将使用无根树</li>
<li><ul>
<li>号通配符 &lt;dubbo:reference group=“<em>“ version=“</em>“ /&gt;，可订阅服务的所有分组和所有版本的提供者</li>
</ul>
</li>
<li>注意：使用zk进行注册中心配置的时候，需要对依赖包尽进行配置</li>
</ol>
<blockquote>
<p>Zookeeper 单机配置:</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">address</span>=<span class="string">"zookeeper://10.20.153.10:2181"</span> /&gt;</span> </span><br><span class="line"><span class="comment">&lt;!--或者--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">protocol</span>=<span class="string">"zookeeper"</span> <span class="attr">address</span>=<span class="string">"10.20.153.10:2181"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>Zookeeper 集群配置：</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">address</span>=<span class="string">"zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181"</span> /&gt;</span> </span><br><span class="line"><span class="comment">&lt;!--或者--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">protocol</span>=<span class="string">"zookeeper"</span> <span class="attr">address</span>=<span class="string">"10.20.153.10:2181,10.20.153.11:2181,10.20.153.12:2181"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>同一 Zookeeper，分成多组注册中心:</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">id</span>=<span class="string">"chinaRegistry"</span> <span class="attr">protocol</span>=<span class="string">"zookeeper"</span> <span class="attr">address</span>=<span class="string">"10.20.153.10:2181"</span> <span class="attr">group</span>=<span class="string">"china"</span> /&gt;</span> </span><br><span class="line"><span class="tag">&lt;<span class="name">dubbo:registry</span> <span class="attr">id</span>=<span class="string">"intlRegistry"</span> <span class="attr">protocol</span>=<span class="string">"zookeeper"</span> <span class="attr">address</span>=<span class="string">"10.20.153.10:2181"</span> <span class="attr">group</span>=<span class="string">"intl"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="使用redis作为配置中心"><a href="#使用redis作为配置中心" class="headerlink" title="使用redis作为配置中心"></a>使用redis作为配置中心</h3><p><img src="blogimg/dubbo/5.jpg" alt=""></p>
<p>使用 Redis 的 Key/Map 结构存储数据结构：主 Key 为服务名和类型，Map 中的 Key 为 URL 地址，Map 中的 Value 为过期时间，用于判断脏数据，脏数据由监控中心删除     </p>
<p>具体流程将上图，因为使用很少，暂时不做讨论</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/dubbo深入（四）- 集群架构设计/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/dubbo深入（四）- 集群架构设计/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="深入dubbo（四）-集群架构设计"><a href="#深入dubbo（四）-集群架构设计" class="headerlink" title="深入dubbo（四）- 集群架构设计"></a>深入dubbo（四）- 集群架构设计</h2><p>这次跟踪源代码，看一看dubbo在进行远程调用的时候进行了那些方法</p>
<ol>
<li>首先调用我们声明的接口方法</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">String hello = demoService.sayHello(<span class="string">"world"</span>); <span class="comment">// 执行远程方法</span></span><br></pre></td></tr></table></figure>
<ol start="2">
<li>很明显进入了动态代理类中 注意返回值</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">InvokerInvocationHandler</span> <span class="keyword">implements</span> <span class="title">InvocationHandler</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> Invoker&lt;?&gt; invoker;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">InvokerInvocationHandler</span><span class="params">(Invoker&lt;?&gt; handler)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.invoker = handler;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">invoke</span><span class="params">(Object proxy, Method method, Object[] args)</span> <span class="keyword">throws</span> Throwable </span>&#123;</span><br><span class="line">        String methodName = method.getName();</span><br><span class="line">        Class&lt;?&gt;[] parameterTypes = method.getParameterTypes();</span><br><span class="line">        <span class="keyword">if</span> (method.getDeclaringClass() == Object.class) &#123;</span><br><span class="line">            <span class="keyword">return</span> method.invoke(invoker, args);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">"toString"</span>.equals(methodName) &amp;&amp; parameterTypes.length == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> invoker.toString();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">"hashCode"</span>.equals(methodName) &amp;&amp; parameterTypes.length == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> invoker.hashCode();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">"equals"</span>.equals(methodName) &amp;&amp; parameterTypes.length == <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> invoker.equals(args[<span class="number">0</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> invoker.invoke(<span class="keyword">new</span> RpcInvocation(method, args)).recreate();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol start="3">
<li>上一步的return方法中我们需要进一步分析invoke（xxx）方法的过程</li>
</ol>
<p><img src="blogimg/dubbo/1.png" alt=""></p>
<ol start="4">
<li>来到了第一个关键的类中 AbstractClusterInvoker 通过 下图中的两个方法我们找到了 下一个关键directory</li>
</ol>
<p><img src="blogimg/dubbo/2.png" alt=""></p>
<p><img src="blogimg/dubbo/3.png" alt=""></p>
<ol start="5">
<li>来到了directory类中 list方法是返回一个所需要的invoke结果集合 中间使用directory 返回所有集合和使用router对结果集进行筛选</li>
</ol>
<p><img src="blogimg/dubbo/4.png" alt=""></p>
<p><img src="blogimg/dubbo/5.png" alt=""></p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/dubbo学习和使用（八）dubbo配置参考/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/dubbo学习和使用（八）dubbo配置参考/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h3 id="dubbo-service-dubbo-service"><a href="#dubbo-service-dubbo-service" class="headerlink" title="dubbo:service(dubbo:service)"></a>dubbo:service(<a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a>)</h3><p>这个配置是针对服务端的，用来暴露服务端可以对外提供的服务信息</p>
<blockquote>
<p>对应的配置类com.alibaba.dubbo.config.ServiceConfig</p>
</blockquote>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>interface</td>
<td>-</td>
<td>class</td>
<td>必填</td>
<td>-</td>
<td>服务发现</td>
<td>服务接口名</td>
<td>1.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>ref</td>
<td>-</td>
<td>object</td>
<td>必填</td>
<td>-</td>
<td>服务发现</td>
<td>服务对象实现引用</td>
<td>1.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>version</td>
<td>version</td>
<td>string</td>
<td>可选</td>
<td>0.0.0</td>
<td>服务发现</td>
<td>服务版本，建议使用两位数字版本，如：1.0，通常在接口不兼容是版本号才需要升级</td>
<td>1.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>group</td>
<td>group</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务发现</td>
<td>服务分组，当一个借口有多个实现，可以用分组区分</td>
<td>1.0.7以上版本</td>
<td></td>
</tr>
<tr>
<td>path</td>
<td></td>
<td>string</td>
<td>可选</td>
<td>缺省为接口</td>
<td>服务发现</td>
<td>服务路径</td>
<td>1.0.12以上版本</td>
<td></td>
</tr>
<tr>
<td>delay</td>
<td>delay</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>延迟注册服务时间(毫秒)，设为-1时，表示延迟到Spring容器初始化完成时暴露服务</td>
<td>1.0.14以上版本</td>
<td></td>
</tr>
<tr>
<td>timeout</td>
<td>timeout</td>
<td>int</td>
<td>可选</td>
<td>1000</td>
<td>性能调优</td>
<td>远程服务调用超时时间(毫秒)</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>retries</td>
<td>retries</td>
<td>int</td>
<td>可选</td>
<td>2</td>
<td>性能调优</td>
<td>远程服务调用重试次数，不包括第一次调用，0为不需要重试</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>connections</td>
<td>connections</td>
<td>boolean</td>
<td>可选</td>
<td>100</td>
<td>性能调优</td>
<td>对每个提供者的最大连接数，rmi、http、hesslan等多连接协议表示限制连接数，dubbo等长链接协议表示建立的长连接个数</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>loadbalance</td>
<td>loadbalance</td>
<td>string</td>
<td>可选</td>
<td>random</td>
<td>性能调优</td>
<td>负载均衡策略，可选值：random，roundrobin，leastactice，分别表示：随机，轮询，最少活跃调用</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>async</td>
<td>async</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>性能调优</td>
<td>是否缺省异步执行，不可靠异步，只是忽略返回值，不阻塞执行线程</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>stub</td>
<td>stub</td>
<td>class/boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为ture，表示使用缺省代理类名，即：接口名+Local后缀，服务接口客户端本地代理类名，用于在客户端执行本地逻辑，如本地缓存等。该本地代理类的构造函数必须允许传入远程代理对象，构造函数如：publicxxxServiceLocal(XxxServicexxxService)</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>mock</td>
<td>mock</td>
<td>class/boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，表示使用缺省Mock类名，即：接口名+Mock后缀，服务接口调用失败Mock实现类，该Mock类必须有一个无参构造函数，与Local的区别在于，Local总是被执行，而Mock只在出现非业务异常(比如超时，网络异常等)时执行，Local在远程调用之前执行，Mock在远程调用后执行</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>token</td>
<td>token</td>
<td>string/bollean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>令牌验证，为空表示不开启。如果为true，表示随机生成动态令牌，否则使用静态令牌。令牌的作用是防止消费者绕过注册中心直接访问，保证注册中心的授权功能有效。如果使用点对点调用，需要关闭令牌功能</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>registry</td>
<td>-</td>
<td>string</td>
<td>可选</td>
<td>缺省向所有registry注册</td>
<td>配置关联</td>
<td>向指定注册中心注册<a href="dubbo:registry" target="_blank" rel="noopener">dubbo:registry</a>的属性为id的value；在向多个注册中心注册时，多个id使用逗号分隔；如果不想讲该服务注册到任何registry，可将值设置N/A</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>provider</td>
<td>-</td>
<td>string</td>
<td>可选</td>
<td>缺省使用第一个provider配置</td>
<td>配置关联</td>
<td>指定provider，值为<a href="dubbo:provider" target="_blank" rel="noopener">dubbo:provider</a>的id属性</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>deprecated</td>
<td>deprecated</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>服务是否过时，如果设置为true，消费方引用时将打印服务过时警告error日志</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>dynamic</td>
<td>dynamic</td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>服务治理</td>
<td>服务是否动态注册，如果设为false，注册后将显示disable状态，需要人工启用；并且服务提供者停止时，也不会自动取消注册，需要人工禁用</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>accesslog</td>
<td>accesslog</td>
<td>string/boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，将向logger中输入访问日志，也可以填写访问日志文件路径，直接把访问日志输出到指定文件</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>owner</td>
<td>owner</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>服务责任人，用于服务治理，请填写公司负责人邮箱前缀</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>document</td>
<td>document</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>服务文档URL</td>
<td>1.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>weight</td>
<td>weight</td>
<td>int</td>
<td>可选</td>
<td>-</td>
<td>服务调优</td>
<td>服务权重</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>executes</td>
<td>executes</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>服务提供者每个服务方法最大可并行请求数</td>
<td></td>
<td></td>
</tr>
<tr>
<td>actives</td>
<td>actives</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>服务消费者每个服务方法最大并发调用数</td>
<td></td>
<td></td>
</tr>
<tr>
<td>proxy</td>
<td>proxy</td>
<td>string</td>
<td>可选</td>
<td>javassist</td>
<td>性能调优</td>
<td>省城动态代理方法，可选：jdk/javassist</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>cluster</td>
<td>cluster</td>
<td>stirng</td>
<td>可选</td>
<td>failover</td>
<td>性能调优</td>
<td>集群方式，可选:failover/failfast/failsafe/failback/forking</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>filter</td>
<td>service.filter</td>
<td>string</td>
<td>可选</td>
<td>default</td>
<td>性能调优</td>
<td>服务提供方远程调用过程拦截器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>listener</td>
<td>exporter.listener</td>
<td>string</td>
<td>可选</td>
<td>default</td>
<td>性能调优</td>
<td>服务提供方导出服务监听器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>protocol</td>
<td>-</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>配置关联</td>
<td>使用指定的协议暴露服务，在使用多协议时，<a href="dubbo:protocol" target="_blank" rel="noopener">dubbo:protocol</a>的id属性的value,使用逗号分隔</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>layer</td>
<td>layer</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>服务提供者所在的分层。如：biz,dao,intl:web,china:acton</td>
<td>2.0.7以上版本</td>
<td></td>
</tr>
<tr>
<td>register</td>
<td>register</td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>服务治理</td>
<td>该协议的服务是否注册到注册中心</td>
<td>2.0.8以上版本</td>
<td></td>
</tr>
</tbody>
</table>
<p>注意：头四个是最重要的属性dubbo通过这些属性来唯一的标示一个service</p>
<h3 id="dubbo-reference"><a href="#dubbo-reference" class="headerlink" title="dubbo:reference"></a>dubbo:reference</h3><p>这个配置是针对消费者端的，消费中通过这个类发起请求向服务端进行调用</p>
<blockquote>
<p>对应的配置类com.alibaba.dubbo.config.ReferenceConfig</p>
</blockquote>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td>-</td>
<td>string</td>
<td>必填</td>
<td>-</td>
<td>配置关联</td>
<td>服务应用beanid</td>
<td>1.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>interface</td>
<td>-</td>
<td>class</td>
<td>必填</td>
<td>-</td>
<td>服务发现</td>
<td>服务接口名</td>
<td>1.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>version</td>
<td>version</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务发现</td>
<td>服务版本，与服务提供者的版本保持一致</td>
<td>1.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>group</td>
<td>group</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务发现</td>
<td>服务分组，当一个借口有多个实现，可以用分组区分，必须和服务提供方一致</td>
<td>1.0.7版本</td>
<td></td>
</tr>
<tr>
<td>timeout</td>
<td>timeout</td>
<td>long</td>
<td>可选</td>
<td>缺省使用<a href="dubbo:consumer" target="_blank" rel="noopener">dubbo:consumer</a>的timeout</td>
<td>性能调优</td>
<td>服务方法调用超时时间(毫秒)</td>
<td>1.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>retries</td>
<td>retries</td>
<td>int</td>
<td>可选</td>
<td>缺省使用<a href="dubbo:consumer" target="_blank" rel="noopener">dubbo:consumer</a>的retries</td>
<td>性能调优</td>
<td>远程服务调用重试次数，不包括第一次调用，不需要重试请设置为0</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>connections</td>
<td>connections</td>
<td>int</td>
<td>可选</td>
<td>缺省使用的connections</td>
<td>性能调优</td>
<td>对每个提供者的最大连接数，rmi、http、hessian等短连接协议表示限制连接数，dubbo等长连接协表示建立的长连接个数</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>loadbalance</td>
<td>loadbalance</td>
<td>string</td>
<td>可选</td>
<td>缺省使用的loadbalance</td>
<td>性能调优</td>
<td>负载均衡策略，可选值：random,roundrobin,leastactive，分别表示：随机，轮循，最少活跃调用</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>sync</td>
<td>sync</td>
<td>boolean</td>
<td>可选</td>
<td>缺省使用的async</td>
<td>性能调优</td>
<td>是否异步执行，不可靠异步，只是忽略返回值，不阻塞执行线程</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>generic</td>
<td>generic</td>
<td>boolean</td>
<td>可选</td>
<td>缺省使用的generic</td>
<td>服务治理</td>
<td>是否缺省泛化接口，如果为泛化接口，将返回GenericService</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>check</td>
<td>check</td>
<td>boolean</td>
<td>可选</td>
<td>缺省使用的check</td>
<td>服务治理</td>
<td>启动时检查提供者是否存在，true报错，false忽略</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>url</td>
<td><url></url></td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>点对点直连服务提供者地址，将绕过注册中心</td>
<td>1.0.6以上版本</td>
<td></td>
</tr>
<tr>
<td>stub</td>
<td>stub</td>
<td>class/boolean</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>服务接口客户端本地代理类名，用于在客户端执行本地逻辑，如本地缓存等，该本地代理类的构造函数必须允许传入远程代理对象，构造函数如：publicXxxServiceLocal(XxxServicexxxService)</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>mock</td>
<td>mock</td>
<td>class/boolean</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>服务接口调用失败Mock实现类名，该Mock类必须有一个无参构造函数，与Local的区别在于，Local总是被执行，而Mock只在出现非业务异常(比如超时，网络异常等)时执行，Local在远程调用之前执行，Mock在远程调用后执行</td>
<td>1.0.13以上版本</td>
<td></td>
</tr>
<tr>
<td>cache</td>
<td>cache</td>
<td>string/boolean</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>以调用参数为key，缓存返回结果。可选：lru,threadlocal,jcache等</td>
<td>2.1.0以上版本</td>
<td></td>
</tr>
<tr>
<td>validation</td>
<td>validation</td>
<td>boolean</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>是否启用JSR303标准注解验证，如果启用，将对方法参数上的注解进行校验</td>
<td>2.1.0以上版本</td>
<td></td>
</tr>
<tr>
<td>proxy</td>
<td>proxy</td>
<td>boolean</td>
<td>可选</td>
<td>javassist</td>
<td>性能调优</td>
<td>选择动态代理实现策略，可选：javassist,jdk</td>
<td>2.0.2以上版本</td>
<td></td>
</tr>
<tr>
<td>client</td>
<td>client</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>性能调优</td>
<td>客户端传输类型设置，如Dubbo协议的netty或mina</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>registry</td>
<td>-</td>
<td>string</td>
<td>可选</td>
<td>缺省将从所有注册中心获服务列表后合并结果</td>
<td>配置关联</td>
<td>从指定注册中心注册获取服务列表，在多个注册中心时使用，值为的id属性，多个注册中心ID用逗号分隔</td>
<td>2.0.0以上版本</td>
<td></td>
</tr>
<tr>
<td>owner</td>
<td>owner</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>调用服务负责人，用于服务治理，请填写负责人公司邮箱前缀</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>actives</td>
<td>actives</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>服务消费者每个服务方法最大并发调用数</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>cluster</td>
<td>cluster</td>
<td>string</td>
<td>可选</td>
<td>failover</td>
<td>性能优化</td>
<td>集群方式，可选：failover/failfast/failsafe/failback/forking</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>filter</td>
<td>reference.filter</td>
<td>string</td>
<td>可选</td>
<td>default</td>
<td>性能调优</td>
<td>服务消费方远程调用过程拦截器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>listener</td>
<td>invoker.listener</td>
<td>string</td>
<td>可选</td>
<td>default</td>
<td>性能调优</td>
<td>服务消费方引用服务监听器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>layer</td>
<td>layer</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>服务调用者所在的分层。如：biz、dao、intl:web、china:acton</td>
<td>2.0.7以上版本</td>
<td></td>
</tr>
<tr>
<td>init</td>
<td>init</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>性能调优</td>
<td>是否在afterPropertiesSet()时饥饿初始化引用，否则等到有人注入或引用该实例时再初始化</td>
<td>2.0.10以上版本</td>
<td></td>
</tr>
<tr>
<td>protocol</td>
<td>protocol</td>
<td>string</td>
<td>可选</td>
<td>-</td>
<td>服务治理</td>
<td>只调用指定协议的服务提供方，其他协议忽略</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<blockquote>
<p>注意：头四个是最重要的属性dubbo通过这些属性来唯一的标示一个service</p>
</blockquote>
<h3 id="dubbo-protocol-dubbo-protocol"><a href="#dubbo-protocol-dubbo-protocol" class="headerlink" title="dubbo:protocol(dubbo:protocol)"></a>dubbo:protocol(<a href="dubbo:protocol" target="_blank" rel="noopener">dubbo:protocol</a>)</h3><p>服务提供者协议配置。对应的配置类：com.alibaba.dubbo.config.ProtocolConfig。同时，如果需要支持多协议，可以声明多个<a href="dubbo:protocol" target="_blank" rel="noopener">dubbo:protocol</a>标签，并在<a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a>中通过protocol属性指定使用的协议。</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td>string</td>
<td>可选</td>
<td>dubbo</td>
<td>配置关联</td>
<td>协议BeanId，可以在中引用此ID，如果ID不填，缺省和name属性值一样，重复则在name后加序号。</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>name</td>
<td>string</td>
<td>必填</td>
<td>dubbo</td>
<td>性能调优</td>
<td>协议名称</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>port</td>
<td>int</td>
<td>可选</td>
<td>dubbo协议缺省端口为20880，rmi协议缺省端口为1099，http和hessian协议缺省端口为80；如果没有配置port，则自动采用默认端口，如果配置为-1，则会分配一个没有被占用的端口。Dubbo2.4.0+，分配的端口在协议缺省端口的基础上增长，确保端口段可控。</td>
<td>服务发现</td>
<td>服务端口</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>host</td>
<td>string</td>
<td>可选</td>
<td>自动查找本机IP</td>
<td>服务发现</td>
<td>-服务主机名，多网卡选择或指定VIP及域名时使用，为空则自动查找本机IP，-建议不要配置，让Dubbo自动获取本机IP</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>threadpool</td>
<td>threadpool</td>
<td>string</td>
<td>可选</td>
<td>fixed</td>
<td>性能调优</td>
<td>线程池类型，可选：fixed/cached</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>threads</td>
<td>threads</td>
<td>int</td>
<td>可选</td>
<td>200</td>
<td>性能调优</td>
<td>服务线程池大小(固定大小)</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>iothreads</td>
<td>threads</td>
<td>int</td>
<td>可选</td>
<td>cpu个数+1</td>
<td>性能调优</td>
<td>io线程池大小(固定大小)</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>accepts</td>
<td>accepts</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>服务提供方最大可接受连接数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>payload</td>
<td>payload</td>
<td>int</td>
<td>可选</td>
<td>8388608(=8M)</td>
<td>性能调优</td>
<td>请求及响应数据包大小限制，单位：字节</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>codec</td>
<td>codec</td>
<td>string</td>
<td>可选</td>
<td>dubbo</td>
<td>性能调优</td>
<td>协议编码方式</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>serialization</td>
<td>serialization</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为hessian2，rmi协议缺省为java，http协议缺省为json</td>
<td>性能调优</td>
<td>协议序列化方式，当协议支持多种序列化方式时使用，比如：dubbo协议的dubbo,hessian2,java,compactedjava，以及http协议的json等</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>accesslog</td>
<td>accesslog</td>
<td>string/boolean</td>
<td>可选</td>
<td>服务治理</td>
<td>设为true，将向logger中输出访问日志，也可填写访问日志文件路径，直接把访问日志输出到指定文件</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>path</td>
<td>string</td>
<td>可选</td>
<td>服务发现</td>
<td>提供者上下文路径，为服务path的前缀</td>
<td>2.0.5以上版本</td>
<td></td>
<td></td>
</tr>
<tr>
<td>transporter</td>
<td>transporter</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为netty</td>
<td>性能调优</td>
<td>协议的服务端和客户端实现类型，比如：dubbo协议的mina,netty等，可以分拆为server和client配置</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>server</td>
<td>server</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为netty，http协议缺省为servlet</td>
<td>性能调优</td>
<td>协议的服务器端实现类型，比如：dubbo协议的mina,netty等，http协议的jetty,servlet等</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>client</td>
<td>client</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为netty</td>
<td>性能调优</td>
<td>协议的客户端实现类型，比如：dubbo协议的mina,netty等</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>dispatcher</td>
<td>dispatcher</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为all</td>
<td>性能调优</td>
<td>协议的消息派发方式，用于指定线程模型，比如：dubbo协议的all,direct,message,execution,connection等</td>
<td>2.1.0以上版本</td>
</tr>
<tr>
<td>queues</td>
<td>queues</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>线程池队列大小，当线程池满时，排队等待执行的队列大小，建议不要设置，当线程程池时应立即失败，重试其它服务提供机器，而不是排队，除非有特殊需求。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>charset</td>
<td>charset</td>
<td>string</td>
<td>可选</td>
<td>UTF-8</td>
<td>性能调优</td>
<td>序列化编码</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>buffer</td>
<td>buffer</td>
<td>int</td>
<td>可选</td>
<td>8192</td>
<td>性能调优</td>
<td>网络读写缓冲区大小</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>heartbeat</td>
<td>heartbeat</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>心跳间隔，对于长连接，当物理层断开时，比如拔网线，TCP的FIN消息来不及发送，对方收不到断开事件，此时需要心跳来帮助检查连接是否已断开</td>
<td>2.0.10以上版本</td>
</tr>
<tr>
<td>telnet</td>
<td>telnet</td>
<td>string</td>
<td>可选</td>
<td>服务治理</td>
<td>所支持的telnet命令，多个命令用逗号分隔</td>
<td>2.0.5以上版本</td>
<td></td>
</tr>
<tr>
<td>register</td>
<td>register</td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>服务治理</td>
<td>该协议的服务是否注册到注册中心</td>
<td>2.0.8以上版本</td>
</tr>
<tr>
<td>contextpath</td>
<td>contextpath</td>
<td>String</td>
<td>可选</td>
<td>缺省为空串</td>
<td>服务治理</td>
<td>2.0.6以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-registry-dubbo-registry"><a href="#dubbo-registry-dubbo-registry" class="headerlink" title="dubbo:registry(dubbo:registry)"></a>dubbo:registry(<a href="dubbo:registry" target="_blank" rel="noopener">dubbo:registry</a>)</h3><p>注册中心配置。对应的配置类： com.alibaba.dubbo.config.RegistryConfig。同时如果有多个不同的注册中心，可以声明多个 <a href="dubbo:registry" target="_blank" rel="noopener">dubbo:registry</a> 标签，并在 <a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a> 或 <a href="dubbo:reference" target="_blank" rel="noopener">dubbo:reference</a> 的 registry 属性指定使用的注册中心。</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td></td>
<td>string</td>
<td>可选</td>
<td></td>
<td>配置关联</td>
<td>注册中心引用BeanId，可以在<a href="dubbo:serviceregistry=&quot;&quot;" target="_blank" rel="noopener">dubbo:serviceregistry=&quot;&quot;</a>或<a href="dubbo:referenceregistry=&quot;&quot;" target="_blank" rel="noopener">dubbo:referenceregistry=&quot;&quot;</a>中引用此ID</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>address</td>
<td><a href="host:port" target="_blank" rel="noopener">host:port</a></td>
<td>string</td>
<td>必填</td>
<td></td>
<td>服务发现</td>
<td>注册中心服务器地址，如果地址没有端口缺省为9090，同一集群内的多个地址用逗号分隔，如：ip:port,ip:port，不同集群的注册中心，请配置多个<a href="dubbo:registry" target="_blank" rel="noopener">dubbo:registry</a>标签</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>protocol</td>
<td><protocol></protocol></td>
<td>string</td>
<td>可选</td>
<td>dubbo</td>
<td>服务发现</td>
<td>注同中心地址协议，支持dubbo,http,local三种协议，分别表示，dubbo地址，http地址，本地注册中心</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>port</td>
<td><port></port></td>
<td>int</td>
<td>可选</td>
<td>9090</td>
<td>服务发现</td>
<td>注册中心缺省端口，当address没有带端口时使用此端口做为缺省值</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>username</td>
<td><username></username></td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>登录注册中心用户名，如果注册中心不需要验证可不填</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>password</td>
<td><password></password></td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>登录注册中心密码，如果注册中心不需要验证可不填</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>transport</td>
<td>registry.transporter</td>
<td>string</td>
<td>可选</td>
<td>netty</td>
<td>性能调优</td>
<td>网络传输方式，可选mina,netty</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>timeout</td>
<td>registry.timeout</td>
<td>int</td>
<td>可选</td>
<td>5000</td>
<td>性能调优</td>
<td>注册中心请求超时时间(毫秒)</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>session</td>
<td>registry.session</td>
<td>int</td>
<td>可选</td>
<td>60000</td>
<td>性能调优</td>
<td>注册中心会话超时时间(毫秒)，用于检测提供者非正常断线后的脏数据，比如用心跳检测的实现，此时间就是心跳间隔，不同注册中心实现不一样。</td>
<td>2.1.0以上版本</td>
</tr>
<tr>
<td>file</td>
<td>registry.file</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>使用文件缓存注册中心地址列表及服务提供者列表，应用重启时将基于此文件恢复，注意：两个注册中心不能使用同一文件存储</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>wait</td>
<td>registry.wait</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>停止时等待通知完成时间(毫秒)</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>check</td>
<td>check</td>
<td>boolean</td>
<td>可选</td>
<td>true</td>
<td>服务治理</td>
<td>注册中心不存在时，是否报错</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>register</td>
<td>register</td>
<td>boolean</td>
<td>可选</td>
<td>true</td>
<td>服务治理</td>
<td>是否向此注册中心注册服务，如果设为false，将只订阅，不注册</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>subscribe</td>
<td>subscribe</td>
<td>boolean</td>
<td>可选</td>
<td>true</td>
<td>服务治理</td>
<td>是否向此注册中心订阅服务，如果设为false，将只注册，不订阅</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>dynamic</td>
<td>dynamic</td>
<td>boolean</td>
<td>可选</td>
<td>true</td>
<td>服务治理</td>
<td>服务是否动态注册，如果设为false，注册后将显示后disable状态，需人工启用，并且服务提供者停止时，也不会自动取消册，需人工禁用。</td>
<td>2.0.5以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-monitor"><a href="#dubbo-monitor" class="headerlink" title="dubbo:monitor"></a>dubbo:monitor</h3><p>监控中心配置。对应的配置类： com.alibaba.dubbo.config.MonitorConfig</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>protocol</td>
<td>protocol</td>
<td>string</td>
<td>可选</td>
<td>dubbo</td>
<td>服务治理</td>
<td>监控中心协议，如果为protocol=”registry”，表示从注册中心发现监控中心地址，否则直连监控中心。</td>
<td>2.0.9以上版本</td>
</tr>
<tr>
<td>address</td>
<td><url></url></td>
<td>string</td>
<td>可选</td>
<td>N/A</td>
<td>服务治理</td>
<td>直连监控中心服务器地址，address=”10.20.130.230:12080”</td>
<td>1.0.16以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-applicationdubbo-application"><a href="#dubbo-applicationdubbo-application" class="headerlink" title="dubbo:applicationdubbo:application"></a>dubbo:application<a href="dubbo:application" target="_blank" rel="noopener">dubbo:application</a></h3><p>应用信息配置。对应的配置类：com.alibaba.dubbo.config.ApplicationConfig</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td>application</td>
<td>string</td>
<td>必填</td>
<td></td>
<td>服务治理</td>
<td>当前应用名称，用于注册中心计算应用间依赖关系，注意：消费者和提供者应用名不要一样，此参数不是匹配条件，你当前项目叫什么名字就填什么，和提供者消费者角色无关，比如：kylin应用调用了morgan应用的服务，则kylin项目配成kylin，morgan项目配成morgan，可能kylin也提供其它服务给别人使用，但kylin项目永远配成kylin，这样注册中心将显示kylin依赖于morgan</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>version</td>
<td>application.version</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>当前应用的版本</td>
<td>2.2.0以上版本</td>
</tr>
<tr>
<td>owner</td>
<td>owner</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>应用负责人，用于服务治理，请填写负责人公司邮箱前缀</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>organization</td>
<td>organization</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>组织名称(BU或部门)，用于注册中心区分服务来源，此配置项建议不要使用autoconfig，直接写死在配置中，比如china,intl,itu,crm,asc,dw,aliexpress等</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>architecture</td>
<td>architecture</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>用于服务分层对应的架构。如，intl、china。不同的架构使用不同的分层。</td>
<td>2.0.7以上版本</td>
</tr>
<tr>
<td>environment</td>
<td>environment</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>应用环境，如：develop/test/product，不同环境使用不同的缺省值，以及作为只用于开发测试功能的限制条件</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>compiler</td>
<td>compiler</td>
<td>string</td>
<td>可选</td>
<td>javassist</td>
<td>性能优化</td>
<td>Java字节码编译器，用于动态类的生成，可选：jdk或javassist</td>
<td>2.1.0以上版本</td>
</tr>
<tr>
<td>logger</td>
<td>logger</td>
<td>string</td>
<td>可选</td>
<td>slf4j</td>
<td>性能优化</td>
<td>日志输出方式，可选：slf4j,jcl,log4j,jdk</td>
<td>2.2.0以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-moduledubbo-module"><a href="#dubbo-moduledubbo-module" class="headerlink" title="dubbo:moduledubbo:module"></a>dubbo:module<a href="dubbo:module" target="_blank" rel="noopener">dubbo:module</a></h3><p>模块信息配置。对应的配置类 com.alibaba.dubbo.config.ModuleConfig</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td>module</td>
<td>string</td>
<td>必填</td>
<td></td>
<td>服务治理</td>
<td>当前模块名称，用于注册中心计算模块间依赖关系</td>
<td>2.2.0以上版本</td>
</tr>
<tr>
<td>version</td>
<td>module.version</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>当前模块的版本</td>
<td>2.2.0以上版本</td>
</tr>
<tr>
<td>owner</td>
<td>owner</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>模块负责人，用于服务治理，请填写负责人公司邮箱前缀</td>
<td>2.2.0以上版本</td>
</tr>
<tr>
<td>organization</td>
<td>organization</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>组织名称(BU或部门)，用于注册中心区分服务来源，此配置项建议不要使用autoconfig，直接写死在配置中，比如china,intl,itu,crm,asc,dw,aliexpress等</td>
<td>2.2.0以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-provider-lt-dubbo：provider-gt"><a href="#dubbo-provider-lt-dubbo：provider-gt" class="headerlink" title="dubbo:provider(&lt;dubbo：provider&gt;)"></a>dubbo:provider(&lt;dubbo：provider&gt;)</h3><p>服务提供者缺省值配置。对应的配置类： com.alibaba.dubbo.config.ProviderConfig。同时该标签为 <a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a> 和 <a href="dubbo:protocol" target="_blank" rel="noopener">dubbo:protocol</a> 标签的缺省值设置。（就是service和service对应的protocol的默认配置）</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td></td>
<td>string</td>
<td>可选</td>
<td>dubbo</td>
<td>配置关联</td>
<td>协议BeanId，可以在<a href="dubbo:serviceproivder=&quot;&quot;" target="_blank" rel="noopener">dubbo:serviceproivder=&quot;&quot;</a>中引用此ID</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>protocol</td>
<td><protocol></protocol></td>
<td>string</td>
<td>可选</td>
<td>dubbo</td>
<td>性能调优</td>
<td>协议名称</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>host</td>
<td><host></host></td>
<td>string</td>
<td>可选</td>
<td>自动查找本机IP</td>
<td>服务发现</td>
<td>服务主机名，多网卡选择或指定VIP及域名时使用，为空则自动查找本机IP，建议不要配置，让Dubbo自动获取本机IP</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>threads</td>
<td>threads</td>
<td>int</td>
<td>可选</td>
<td>200</td>
<td>性能调优</td>
<td>服务线程池大小(固定大小)</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>payload</td>
<td>payload</td>
<td>int</td>
<td>可选</td>
<td>8388608(=8M)</td>
<td>性能调优</td>
<td>请求及响应数据包大小限制，单位：字节</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>path</td>
<td><path></path></td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务发现</td>
<td>提供者上下文路径，为服务path的前缀</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>server</td>
<td>server</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为netty，http协议缺省为servlet</td>
<td>性能调优</td>
<td>协议的服务器端实现类型，比如：dubbo协议的mina,netty等，http协议的jetty,servlet等</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>client</td>
<td>client</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为netty</td>
<td>性能调优</td>
<td>协议的客户端实现类型，比如：dubbo协议的mina,netty等</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>codec</td>
<td>codec</td>
<td>string</td>
<td>可选</td>
<td>dubbo</td>
<td>性能调优</td>
<td>协议编码方式</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>serialization</td>
<td>serialization</td>
<td>string</td>
<td>可选</td>
<td>dubbo协议缺省为hessian2，rmi协议缺省为java，http协议缺省为json</td>
<td>性能调优</td>
<td>协议序列化方式，当协议支持多种序列化方式时使用，比如：dubbo协议的dubbo,hessian2,java,compactedjava，以及http协议的json,xml等</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>default</td>
<td></td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>配置关联</td>
<td>是否为缺省协议，用于多协议</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>filter</td>
<td>service.filter</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>服务提供方远程调用过程拦截器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>listener</td>
<td>exporter.listener</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>服务提供方导出服务监听器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>threadpool</td>
<td>threadpool</td>
<td>string</td>
<td>可选</td>
<td>fixed</td>
<td>性能调优</td>
<td>线程池类型，可选：fixed/cached</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>accepts</td>
<td>accepts</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>服务提供者最大可接受连接数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>version</td>
<td>version</td>
<td>string</td>
<td>可选</td>
<td>0.0.0</td>
<td>服务发现</td>
<td>服务版本，建议使用两位数字版本，如：1.0，通常在接口不兼容时版本号才需要升级</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>group</td>
<td>group</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务发现</td>
<td>服务分组，当一个接口有多个实现，可以用分组区分</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>delay</td>
<td>delay</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>延迟注册服务时间(毫秒)，设为1时，表示延迟到Spring容器初始化完成时暴露服务</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>timeout</td>
<td>default.timeout</td>
<td>int</td>
<td>可选</td>
<td>1000</td>
<td>性能调优</td>
<td>远程服务调用超时时间(毫秒)</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>retries</td>
<td>default.retries</td>
<td>int</td>
<td>可选</td>
<td>2</td>
<td>性能调优</td>
<td>远程服务调用重试次数，不包括第一次调用，不需要重试请设为0</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>connections</td>
<td>default.connections</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>对每个提供者的最大连接数，rmi、http、hessian等短连接协议表示限制连接数，dubbo等长连接协表示建立的长连接个数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>loadbalance</td>
<td>default.loadbalance</td>
<td>string</td>
<td>可选</td>
<td>random</td>
<td>性能调优</td>
<td>负载均衡策略，可选值：random,roundrobin,leastactive，分别表示：随机，轮循，最少活跃调用</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>async</td>
<td>default.async</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>性能调优</td>
<td>是否缺省异步执行，不可靠异步，只是忽略返回值，不阻塞执行线程</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>stub</td>
<td>stub</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，表示使用缺省代理类名，即：接口名+Local后缀。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>mock</td>
<td>mock</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，表示使用缺省Mock类名，即：接口名+Mock后缀。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>token</td>
<td>token</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>令牌验证，为空表示不开启，如果为true，表示随机生成动态令牌</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>registry</td>
<td>registry</td>
<td>string</td>
<td>可选</td>
<td>缺省向所有registry注册</td>
<td>配置关联</td>
<td>向指定注册中心注册，在多个注册中心时使用，值为<a href="dubbo:registry" target="_blank" rel="noopener">dubbo:registry</a>的id属性，多个注册中心ID用逗号分隔，如果不想将该服务注册到任何registry，可将值设为N/A</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>dynamic</td>
<td>dynamic</td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>服务治理</td>
<td>服务是否动态注册，如果设为false，注册后将显示后disable状态，需人工启用，并且服务提供者停止时，也不会自动取消册，需人工禁用。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>accesslog</td>
<td>accesslog</td>
<td>string/boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，将向logger中输出访问日志，也可填写访问日志文件路径，直接把访问日志输出到指定文件</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>owner</td>
<td>owner</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>服务负责人，用于服务治理，请填写负责人公司邮箱前缀</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>document</td>
<td>document</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>服务文档URL</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>weight</td>
<td>weight</td>
<td>int</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>服务权重</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>executes</td>
<td>executes</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>服务提供者每服务每方法最大可并行执行请求数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>actives</td>
<td>default.actives</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>每服务消费者每服务每方法最大并发调用数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>proxy</td>
<td>proxy</td>
<td>string</td>
<td>可选</td>
<td>javassist</td>
<td>性能调优</td>
<td>生成动态代理方式，可选：jdk/javassist</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>cluster</td>
<td>default.cluster</td>
<td>string</td>
<td>可选</td>
<td>failover</td>
<td>性能调优</td>
<td>集群方式，可选：failover/failfast/failsafe/failback/forking</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>deprecated</td>
<td>deprecated</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>服务是否过时，如果设为true，消费方引用时将打印服务过时警告error日志</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>queues</td>
<td>queues</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>线程池队列大小，当线程池满时，排队等待执行的队列大小，建议不要设置，当线程程池时应立即失败，重试其它服务提供机器，而不是排队，除非有特殊需求。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>charset</td>
<td>charset</td>
<td>string</td>
<td>可选</td>
<td>UTF8</td>
<td>性能调优</td>
<td>序列化编码</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>buffer</td>
<td>buffer</td>
<td>int</td>
<td>可选</td>
<td>8192</td>
<td>性能调优</td>
<td>网络读写缓冲区大小</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>iothreads</td>
<td>iothreads</td>
<td>int</td>
<td>可选</td>
<td>CPU+1</td>
<td>性能调优</td>
<td>IO线程池，接收网络读写中断，以及序列化和反序列化，不处理业务，业务线程池参见threads配置，此线程池和CPU相关，不建议配置。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>telnet</td>
<td>telnet</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>所支持的telnet命令，多个命令用逗号分隔</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td><a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a></td>
<td>contextpath</td>
<td>contextpath</td>
<td>String</td>
<td>可选</td>
<td>缺省为空串</td>
<td>服务治理</td>
<td></td>
</tr>
<tr>
<td>layer</td>
<td>layer</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>服务提供者所在的分层。如：biz、dao、intl:web、china:acton。</td>
<td>2.0.7以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-consumer-dubbo-consumer"><a href="#dubbo-consumer-dubbo-consumer" class="headerlink" title="dubbo:consumer(dubbo:consumer)"></a>dubbo:consumer(<a href="dubbo:consumer" target="_blank" rel="noopener">dubbo:consumer</a>)</h3><p>服务消费者缺省值配置。配置类： com.alibaba.dubbo.config.ConsumerConfig 。同时该标签为 <a href="dubbo:reference" target="_blank" rel="noopener">dubbo:reference</a> 标签的缺省值设置。</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>timeout</td>
<td>default.timeout</td>
<td>int</td>
<td>可选</td>
<td>1000</td>
<td>性能调优</td>
<td>远程服务调用超时时间(毫秒)</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>retries</td>
<td>default.retries</td>
<td>int</td>
<td>可选</td>
<td>2</td>
<td>性能调优</td>
<td>远程服务调用重试次数，不包括第一次调用，不需要重试请设为0</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>loadbalance</td>
<td>default.loadbalance</td>
<td>string</td>
<td>可选</td>
<td>random</td>
<td>性能调优</td>
<td>负载均衡策略，可选值：random,roundrobin,leastactive，分别表示：随机，轮循，最少活跃调用</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>async</td>
<td>default.async</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>性能调优</td>
<td>是否缺省异步执行，不可靠异步，只是忽略返回值，不阻塞执行线程</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>connections</td>
<td>default.connections</td>
<td>int</td>
<td>可选</td>
<td>100</td>
<td>性能调优</td>
<td>每个服务对每个提供者的最大连接数，rmi、http、hessian等短连接协议支持此配置，dubbo协议长连接不支持此配置</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>generic</td>
<td>generic</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>是否缺省泛化接口，如果为泛化接口，将返回GenericService</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>check</td>
<td>check</td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>服务治理</td>
<td>启动时检查提供者是否存在，true报错，false忽略</td>
<td>1.0.16以上版本</td>
</tr>
<tr>
<td>proxy</td>
<td>proxy</td>
<td>string</td>
<td>可选</td>
<td>javassist</td>
<td>性能调优</td>
<td>生成动态代理方式，可选：jdk/javassist</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>owner</td>
<td>owner</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>调用服务负责人，用于服务治理，请填写负责人公司邮箱前缀</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>actives</td>
<td>default.actives</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>每服务消费者每服务每方法最大并发调用数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>cluster</td>
<td>default.cluster</td>
<td>string</td>
<td>可选</td>
<td>failover</td>
<td>性能调优</td>
<td>集群方式，可选：failover/failfast/failsafe/failback/forking</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>filter</td>
<td>reference.filter</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>服务消费方远程调用过程拦截器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>listener</td>
<td>invoker.listener</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>服务消费方引用服务监听器名称，多个名称用逗号分隔</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>registry</td>
<td></td>
<td>string</td>
<td>可选</td>
<td>缺省向所有registry注册</td>
<td>配置关联</td>
<td>向指定注册中心注册，在多个注册中心时使用，值为<a href="dubbo:registry" target="_blank" rel="noopener">dubbo:registry</a>的id属性，多个注册中心ID用逗号分隔，如果不想将该服务注册到任何registry，可将值设为N/A</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>layer</td>
<td>layer</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>服务调用者所在的分层。如：biz、dao、intl:web、china:acton。</td>
<td>2.0.7以上版本</td>
</tr>
<tr>
<td>init</td>
<td>init</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>性能调优</td>
<td>是否在afterPropertiesSet()时饥饿初始化引用，否则等到有人注入或引用该实例时再初始化。</td>
<td>2.0.10以上版本</td>
</tr>
<tr>
<td>cache</td>
<td>cache</td>
<td>string/boolean</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>以调用参数为key，缓存返回结果，可选：lru,threadlocal,jcache等</td>
<td>Dubbo2.1.0及其以上版本支持</td>
</tr>
<tr>
<td>validation</td>
<td>validation</td>
<td>boolean</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>是否启用JSR303标准注解验证，如果启用，将对方法参数上的注解进行校验</td>
<td>Dubbo2.1.0及其以上版本支持</td>
</tr>
<tr>
<td>timeout</td>
<td>default.timeout</td>
<td>int</td>
<td>可选</td>
<td>1000</td>
<td>性能调优</td>
<td>远程服务调用超时时间(毫秒)</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>retries</td>
<td>default.retries</td>
<td>int</td>
<td>可选</td>
<td>2</td>
<td>性能调优</td>
<td>远程服务调用重试次数，不包括第一次调用，不需要重试请设为0</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>connections</td>
<td>default.connections</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>对每个提供者的最大连接数，rmi、http、hessian等短连接协议表示限制连接数，dubbo等长连接协表示建立的长连接个数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>loadbalance</td>
<td>default.loadbalance</td>
<td>string</td>
<td>可选</td>
<td>random</td>
<td>性能调优</td>
<td>负载均衡策略，可选值：random,roundrobin,leastactive，分别表示：随机，轮循，最少活跃调用</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>async</td>
<td>default.async</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>性能调优</td>
<td>是否缺省异步执行，不可靠异步，只是忽略返回值，不阻塞执行线程</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>stub</td>
<td>stub</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，表示使用缺省代理类名，即：接口名+Local后缀。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>mock</td>
<td>mock</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，表示使用缺省Mock类名，即：接口名+Mock后缀。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>token</td>
<td>token</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>令牌验证，为空表示不开启，如果为true，表示随机生成动态令牌</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>registry</td>
<td>registry</td>
<td>string</td>
<td>可选</td>
<td>缺省向所有registry注册</td>
<td>配置关联</td>
<td>向指定注册中心注册，在多个注册中心时使用，值为<a href="dubbo:registry" target="_blank" rel="noopener">dubbo:registry</a>的id属性，多个注册中心ID用逗号分隔，如果不想将该服务注册到任何registry，可将值设为N/A</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>dynamic</td>
<td>dynamic</td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>服务治理</td>
<td>服务是否动态注册，如果设为false，注册后将显示后disable状态，需人工启用，并且服务提供者停止时，也不会自动取消册，需人工禁用。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>accesslog</td>
<td>accesslog</td>
<td>string/boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设为true，将向logger中输出访问日志，也可填写访问日志文件路径，直接把访问日志输出到指定文件</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>owner</td>
<td>owner</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>服务负责人，用于服务治理，请填写负责人公司邮箱前缀</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>document</td>
<td>document</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>服务文档URL</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>weight</td>
<td>weight</td>
<td>int</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>服务权重</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>executes</td>
<td>executes</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>服务提供者每服务每方法最大可并行执行请求数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>actives</td>
<td>default.actives</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>每服务消费者每服务每方法最大并发调用数</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>proxy</td>
<td>proxy</td>
<td>string</td>
<td>可选</td>
<td>javassist</td>
<td>性能调优</td>
<td>生成动态代理方式，可选：jdk/javassist</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>cluster</td>
<td>default.cluster</td>
<td>string</td>
<td>可选</td>
<td>failover</td>
<td>性能调优</td>
<td>集群方式，可选：failover/failfast/failsafe/failback/forking</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>deprecated</td>
<td>deprecated</td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>服务是否过时，如果设为true，消费方引用时将打印服务过时警告error日志</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>queues</td>
<td>queues</td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>线程池队列大小，当线程池满时，排队等待执行的队列大小，建议不要设置，当线程程池时应立即失败，重试其它服务提供机器，而不是排队，除非有特殊需求。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>charset</td>
<td>charset</td>
<td>string</td>
<td>可选</td>
<td>UTF8</td>
<td>性能调优</td>
<td>序列化编码</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>buffer</td>
<td>buffer</td>
<td>int</td>
<td>可选</td>
<td>8192</td>
<td>性能调优</td>
<td>网络读写缓冲区大小</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>iothreads</td>
<td>iothreads</td>
<td>int</td>
<td>可选</td>
<td>CPU+1</td>
<td>性能调优</td>
<td>IO线程池，接收网络读写中断，以及序列化和反序列化，不处理业务，业务线程池参见threads配置，此线程池和CPU相关，不建议配置。</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>telnet</td>
<td>telnet</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>所支持的telnet命令，多个命令用逗号分隔</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td><a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a></td>
<td>contextpath</td>
<td>contextpath</td>
<td>String</td>
<td>可选</td>
<td>缺省为空串</td>
<td>服务治理</td>
<td></td>
</tr>
<tr>
<td>layer</td>
<td>layer</td>
<td>string</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>服务提供者所在的分层。如：biz、dao、intl:web、china:acton。</td>
<td>2.0.7以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-method-dubbo-method"><a href="#dubbo-method-dubbo-method" class="headerlink" title="dubbo:method (dubbo:method)"></a>dubbo:method (<a href="dubbo:method" target="_blank" rel="noopener">dubbo:method</a>)</h3><p>方法级配置。对应的配置类： com.alibaba.dubbo.config.MethodConfig。同时该标签为 <a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a> 或 <a href="dubbo:reference" target="_blank" rel="noopener">dubbo:reference</a> 的子标签，用于控制到方法级。</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td></td>
<td>string</td>
<td>必填</td>
<td></td>
<td>标识</td>
<td>方法名</td>
<td>1.0.8以上版本</td>
</tr>
<tr>
<td>timeout</td>
<td><metodname>.timeout</metodname></td>
<td>int</td>
<td>可选</td>
<td>缺省为的timeout</td>
<td>性能调优</td>
<td>方法调用超时时间(毫秒)</td>
<td>1.0.8以上版本</td>
</tr>
<tr>
<td>retries</td>
<td><metodname>.retries</metodname></td>
<td>int</td>
<td>可选</td>
<td>缺省为<a href="dubbo:reference" target="_blank" rel="noopener">dubbo:reference</a>的retries</td>
<td>性能调优</td>
<td>远程服务调用重试次数，不包括第一次调用，不需要重试请设为0</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>loadbalance</td>
<td><metodname>.loadbalance</metodname></td>
<td>string</td>
<td>可选</td>
<td>缺省为的loadbalance</td>
<td>性能调优</td>
<td>负载均衡策略，可选值：random,roundrobin,leastactive，分别表示：随机，轮循，最少活跃调用</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>async</td>
<td><metodname>.async</metodname></td>
<td>boolean</td>
<td>可选</td>
<td>缺省为<a href="dubbo:reference" target="_blank" rel="noopener">dubbo:reference</a>的async</td>
<td>性能调优</td>
<td>是否异步执行，不可靠异步，只是忽略返回值，不阻塞执行线程</td>
<td>1.0.9以上版本</td>
</tr>
<tr>
<td>sent</td>
<td><methodname>.sent</methodname></td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>性能调优</td>
<td>异步调用时，标记sent=true时，表示网络已发出数据</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>actives</td>
<td><metodname>.actives</metodname></td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>每服务消费者最大并发调用限制</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>executes</td>
<td><metodname>.executes</metodname></td>
<td>int</td>
<td>可选</td>
<td>0</td>
<td>性能调优</td>
<td>每服务每方法最大使用线程数限制，此属性只在<a href="dubbo:method" target="_blank" rel="noopener">dubbo:method</a>作为<a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a>子标签时有效</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>deprecated</td>
<td><methodname>.deprecated</methodname></td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>服务方法是否过时，此属性只在<a href="dubbo:method" target="_blank" rel="noopener">dubbo:method</a>作为<a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a>子标签时有效</td>
<td>2.0.5以上版本</td>
</tr>
<tr>
<td>sticky</td>
<td><methodname>.sticky</methodname></td>
<td>boolean</td>
<td>可选</td>
<td>FALSE</td>
<td>服务治理</td>
<td>设置true该接口上的所有方法使用同一个provider.如果需要更复杂的规则，请使用用路由</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>return</td>
<td><methodname>.return</methodname></td>
<td>boolean</td>
<td>可选</td>
<td>TRUE</td>
<td>性能调优</td>
<td>方法调用是否需要返回值,async设置为true时才生效，如果设置为true，则返回future，或回调onreturn等方法，如果设置为false，则请求发送成功后直接返回Null</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>oninvoke</td>
<td>attribute属性，不在URL中体现</td>
<td>String</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>方法执行前拦截</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>onreturn</td>
<td>attribute属性，不在URL中体现</td>
<td>String</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>方法执行返回后拦截</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>onthrow</td>
<td>attribute属性，不在URL中体现</td>
<td>String</td>
<td>可选</td>
<td></td>
<td>性能调优</td>
<td>方法执行有异常拦截</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>cache</td>
<td><methodname>.cache</methodname></td>
<td>string/boolean</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>以调用参数为key，缓存返回结果，可选：lru,threadlocal,jcache等</td>
<td>Dubbo2.1.0及其以上版本支持</td>
</tr>
<tr>
<td>validation</td>
<td><methodname>.validation</methodname></td>
<td>boolean</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>是否启用JSR303标准注解验证，如果启用，将对方法参数上的注解进行校验</td>
<td>Dubbo2.1.0及其以上版本支持</td>
</tr>
</tbody>
</table>
<blockquote>
<p>代码实例</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">interface</span>=<span class="string">"com.xxx.XxxService"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findXxx"</span> <span class="attr">timeout</span>=<span class="string">"3000"</span> <span class="attr">retries</span>=<span class="string">"2"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:reference</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="dubbo-argument-dubbo-argument"><a href="#dubbo-argument-dubbo-argument" class="headerlink" title="dubbo:argument(dubbo:argument)"></a>dubbo:argument(<a href="dubbo:argument" target="_blank" rel="noopener">dubbo:argument</a>)</h3><p>方法参数配置。对应的配置类： com.alibaba.dubbo.config.ArgumentConfig。该标签为 <a href="dubbo:method" target="_blank" rel="noopener">dubbo:method</a> 的子标签，用于方法参数的特征描述，比如：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"findXxx"</span> <span class="attr">timeout</span>=<span class="string">"3000"</span> <span class="attr">retries</span>=<span class="string">"2"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:argument</span> <span class="attr">index</span>=<span class="string">"0"</span> <span class="attr">callback</span>=<span class="string">"true"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:method</span>&gt;</span></span><br></pre></td></tr></table></figure>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>index</td>
<td></td>
<td>int</td>
<td>必填</td>
<td></td>
<td>标识</td>
<td>方法名</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>type</td>
<td></td>
<td>String</td>
<td>与index二选一</td>
<td></td>
<td>标识</td>
<td>通过参数类型查找参数的index</td>
<td>2.0.6以上版本</td>
</tr>
<tr>
<td>callback</td>
<td><metodname><index>.retries</index></metodname></td>
<td>boolean</td>
<td>可选</td>
<td></td>
<td>服务治理</td>
<td>参数是否为callback接口，如果为callback，服务提供方将生成反向代理，可以从服务提供方反向调用消费方，通常用于事件推送.</td>
<td>2.0.6以上版本</td>
</tr>
</tbody>
</table>
<h3 id="dubbo-parameter"><a href="#dubbo-parameter" class="headerlink" title="dubbo:parameter()"></a>dubbo:parameter(<dubbo>)</dubbo></h3><p>选项参数配置。对应的配置类：java.util.Map。同时该标签为<a href="dubbo:protocol" target="_blank" rel="noopener">dubbo:protocol</a>或<a href="dubbo:service" target="_blank" rel="noopener">dubbo:service</a>或<a href="dubbo:provider" target="_blank" rel="noopener">dubbo:provider</a>或<a href="dubbo:reference" target="_blank" rel="noopener">dubbo:reference</a>或<a href="dubbo:consumer" target="_blank" rel="noopener">dubbo:consumer</a>的子标签，用于配置自定义参数，该配置项将作为扩展点设置自定义参数使用。</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>对应URL参数</th>
<th>类型</th>
<th>是否必填</th>
<th>缺省值</th>
<th>作用</th>
<th>描述</th>
<th>兼容性</th>
</tr>
</thead>
<tbody>
<tr>
<td>key</td>
<td>key</td>
<td>string</td>
<td>必填</td>
<td></td>
<td>服务治理</td>
<td>路由参数键</td>
<td>2.0.0以上版本</td>
</tr>
<tr>
<td>value</td>
<td>value</td>
<td>string</td>
<td>必填</td>
<td></td>
<td>服务治理</td>
<td>路由参数值</td>
<td>2.0.0以上版本</td>
</tr>
</tbody>
</table>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"napoli"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:parameter</span> <span class="attr">key</span>=<span class="string">"http://10.20.160.198/wiki/display/dubbo/napoli.queue.name"</span> <span class="attr">value</span>=<span class="string">"xxx"</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:protocol</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:protocol</span> <span class="attr">name</span>=<span class="string">"jms"</span> <span class="attr">p:queue</span>=<span class="string">"xxx"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
  </section>

  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/9/"><i class="fa fa-angle-left"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/9/">9</a><span class="page-number current">10</span><a class="page-number" href="/page/11/">11</a><span class="space">&hellip;</span><a class="page-number" href="/page/14/">14</a><a class="extend next" rel="next" href="/page/11/"><i class="fa fa-angle-right"></i></a>
  </nav>



          </div>
          


          

        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">kyssion</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">133</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                
                  <span class="site-state-item-count">3</span>
                  <span class="site-state-item-name">分类</span>
                
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                
                  <span class="site-state-item-count">2</span>
                  <span class="site-state-item-name">标签</span>
                
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">kyssion</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Mist</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  

  

  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
